zoukankan      html  css  js  c++  java
  • 排序算法(还需补充)

      1 /************
      2 十大排序算法
      3 ***********/
      4 
      5 #include<iostream>
      6 #include<ctime>
      7 using namespace std;
      8 
      9 typedef int T;
     10 
     11 void swap(T &x,T &y)
     12 {
     13     T temp;
     14     temp=x;
     15     x=y;
     16     y=temp;
     17 }
     18 //1,冒泡  原地稳定 o(n^2)
     19 void bubble(T *a, int n)
     20 {
     21     for(int i=0;i<n-1;i++)
     22         for(int j=0;j<n-1-i;j++)
     23         {
     24             if(a[j]>a[j+1])
     25                 swap(a[j],a[j+1]);
     26         }
     27 }
     28 
     29 void improvebubble(T *a, int n)
     30 {
     31     bool over=true;//作指示,若有一次没交换就结束
     32     for(int i=0;i<n-1&&over;i++)
     33     {
     34         over =false;
     35         for(int j=0;j<n-1-i;j++)
     36             if(a[j]>a[j+1])
     37             {
     38                 swap(a[j],a[j+1]);
     39                 over=true;
     40             }
     41     }
     42 }
     43 //2,插排 原地稳定 o(T)=1+2+3+..+n-1=o(n^2)
     44 void insert1(T *a,int n)
     45 {
     46     for(int i=1;i<n;i++)
     47     {
     48         T temp=a[i];
     49         int j;
     50         for(j=i-1;j>=0;j--)//和前面抽出来有序的比较
     51         {
     52             if(a[j]<=temp)
     53                 break;
     54             a[j+1]=a[j];
     55         }
     56         a[j]=temp;
     57     }
     58 }
     59 
     60 int findpos(T *a,int n, T key)
     61 {
     62     int high=n-1,low=0;
     63     while(low<=high)//***这里要有等号,不然high=low(即排查到只剩一个数时)就不判断直接排在前面了
     64     {
     65         int mid=(high+low)/2;
     66         if(key>=a[mid]) //如果相等,定位到其后面,保证稳定排序
     67             low=mid+1;
     68         else if (key<a[mid])
     69             high=mid-1;
     70     }
     71     
     72     return low;
     73 }
     74 void insert2(T *a,int n)
     75 {
     76     for(int i=1;i<n;i++)
     77     {
     78         T temp=a[i];
     79         int pos=findpos(a,i,temp);
     80         for(int j=i-1;j>=pos;j--)
     81         {
     82             a[j+1]=a[j];
     83         }
     84         a[pos]=temp;
     85         cout<<pos<<endl;
     86         for(int i=0;i<n;i++)
     87             cout<<a[i];
     88         cout<<endl;
     89     }
     90 }
     91 
     92 
     93 //3,选择排序 原地不稳定,一次选一个最小的, o(n^2)
     94 void select(T *a,int n)
     95 {
     96     for(int i=0;i<n-1;i++)
     97     {
     98         T min=a[i];
     99         int k=i;//重要一定要让k=i
    100         for(int j=i+1;j<n;j++)
    101         {
    102             if(min>a[j])//找最小的
    103             {
    104                 min=a[j];
    105                 k=j;
    106             }
    107         }
    108         if(i!=k)//重要
    109             swap(a[i],a[k]);//不稳定,比如a[i]不是最小的,它与最小发生交换,打乱了它自己的位置
    110 
    111     }
    112 }
    113 //4.归并排序 非原地稳定 o(nlogn), 需要开辟o(n)的空间
    114 //分治法,每次一分为二,最后将俩部分合并排序
    115 void MergeSort(T *a,int f,int r,int mid)
    116 {
    117     int i=f,j=mid+1;
    118     int m=mid,n=r;
    119     int k=0;
    120     T *temp=new T[r-f+1];//非原地排序,用来合并数组
    121 
    122     while(i<=m && j<=n)
    123     {
    124         if(a[i]<=a[j])//这里等号可保证稳定
    125             temp[k++]=a[i++];
    126         else
    127             temp[k++]=a[j++];
    128     }
    129     while(i<=m)
    130         temp[k++]=a[i++];
    131     while(j<=n)
    132         temp[k++]=a[j++];
    133     for(i=0;i<k;i++)//数组a局部有序
    134         a[f+i]=temp[i];
    135 
    136     delete [] temp;
    137 }
    138 
    139 void Merge(T *a,int f,int r)
    140 {
    141     if(f<r)
    142     {
    143         int mid=(f+r)/2;
    144         Merge(a,f,mid);
    145         Merge(a,mid+1,r);
    146         MergeSort(a,f,r,mid);
    147     }
    148 }
    149 void merge(T *a, int n)
    150 {
    151     Merge(a,0,n-1);    
    152 }
    153 
    154 //5.快排,原地不稳定 o(nlogn)
    155 void Quick(T *a,int f,int r)
    156 {
    157     if(f>=r)
    158         return;
    159     int i=f,j=r;
    160     T temp=a[f];//第一个坑
    161     while(i<j)
    162     {
    163         while(temp<=a[j] && i<j)//有可能越界
    164             j--;
    165         if(i<j)//如果俩者相遇,即跑到挖的坑那了
    166             a[i++]=a[j];//后面的小的数填前面的坑
    167         while(temp>a[i] && i<j)
    168             i++;
    169         if(i<j)
    170             a[j--]=a[i];//用前面的大的数填后面的坑
    171     }
    172     a[i]=temp;//最后一坑
    173     Quick(a,f,i);
    174     Quick(a,i+1,r);
    175 }
    176 void quick(T*a,int n)
    177 {
    178     Quick(a,0,n-1);
    179 }
    180 
    181 //6.计数排序
    182 //只能是整数(或字符)排序,而且要求分布比较均匀,非原地稳定  
    183 //好处是o(n)线性复杂度,方便序列去重操作
    184 void count(T *a,int n)
    185 {
    186     T max=a[0],min=a[0];
    187     int i;
    188     for(i=0;i<n;i++)//找到序列最小值,以确定桶大小
    189     {
    190         if(max<a[i])
    191             max=a[i];
    192         if(min>a[i])
    193             min=a[i];
    194     }
    195     int len=max-min+1;
    196     T* C=new T[len];//记录每个数出现的次数
    197     for(i=0;i<len;i++)
    198         C[i]=0;
    199     for(i=0;i<n;i++)
    200         C[a[i]-min]+=1;
    201     for(i=1;i<len;i++)
    202         C[i]+=C[i-1];
    203 
    204     T *R=new T[n];//
    205     for(i=n-1;i>=0;i--)//倒着来取可保证稳定排序,后面的还排在后面
    206     {
    207         T temp=a[i];
    208         int pos=C[temp-min];
    209         R[pos-1]=temp;//注意这的减一.C统计的的是个数,R是从0开始存储的
    210         C[temp-min]--;
    211     }
    212 
    213     for(i=0;i<n;i++)
    214         a[i]=R[i];
    215 
    216     delete [] C;
    217     delete [] R;
    218 }
    219 //7,希尔排序 分组排序 原地不稳定 
    220 //数组基本有序的情况下更好
    221 void shell1(T *a, int n)
    222 {
    223     for(int gap=n/2;gap>0;gap/=2) //log n
    224         for(int i=gap;i<n;i++)//gap=1就是insertSort  o(n/gap)
    225             for(int j=i-gap;j>=0 && a[j]>a[j+gap];j-=gap) 
    226                 swap(a[j+gap],a[j]);//或者可以先后推找到位置,最后填进去
    227 }
    228 
    229 void shell2(T *a,int n)//??不理解 o(nlogn)
    230 {
    231     int d=n;
    232     while(d>1)
    233     {
    234         d=(d+1)/2;
    235         for(int i=0;i<n-d;i++)
    236             if(a[i+d]<a[i])
    237                 swap(a[i+d],a[i]);
    238     }
    239 }
    240 
    241 
    242 //8,堆排序 大根堆,向下调整 o(nlogn) 原地不稳定 适合处理大文件
    243 void shiftdown(T *a,int n,int i)//
    244 {
    245     int t,flag=0;
    246     while(2*i+1<n && flag==0)//以0为根节点,左右孩子是2i+1,2i+2
    247     {
    248         if(a[i]<a[2*i+1])
    249             t=2*i+1;
    250         else t=i;
    251         if(2*i+2<n)//n是节点数,从1开始计的,而i是从0开始计的
    252             if(a[t]<a[2*i+2])
    253                 t=2*i+2;
    254         if(t!=i)
    255         {
    256             swap(a[i],a[t]);
    257             i=t;//继续往下调整
    258         }
    259         else flag=1;
    260     }
    261 }
    262         
    263 void createMaxHeap(T *a,int n)//建立大根堆,o(n/2)
    264 {
    265     for(int i=n/2;i>=0;i--)//父节点向下调整
    266         shiftdown(a,n,i);
    267 }
    268 
    269 void heapsort(T *a, int n)
    270 {
    271     createMaxHeap(a,n);
    272     int k=n-1;
    273     while(k>0)
    274     {
    275         swap(a[k],a[0]);
    276         k--;
    277         shiftdown(a,k,0);//o(logk)
    278     }
    279 }
    280 
    281 int main()
    282 {
    283     const int n=15;
    284     int a[n]={4,6,5,3,2,1,4,5,6,7,2,8,9,3,1};
    285     shell2(a,n);
    286     for(int i=0;i<n;i++)
    287         cout<<a[i];
    288     cout<<endl;
    289     return 0;
    290 }
  • 相关阅读:
    Security headers quick reference Learn more about headers that can keep your site safe and quickly look up the most important details.
    Missing dollar riddle
    Where Did the Other Dollar Go, Jeff?
    proteus 与 keil 联调
    cisco router nat
    router dhcp and dns listen
    配置802.1x在交换机的端口验证设置
    ASAv931安装&初始化及ASDM管理
    S5700与Cisco ACS做802.1x认证
    playwright
  • 原文地址:https://www.cnblogs.com/fkissx/p/4501998.html
Copyright © 2011-2022 走看看