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 }
  • 相关阅读:
    git回滚分支版本到指定版本
    java的垃圾回收
    java对象模型
    java内存模型
    偏向锁浅析
    maven打包报错:在类路径或引导类路径中找不到程序包 java.lang
    《microsoft sql server 2008技术内幕 t-sql语言基础》
    《SQL基础教程》
    内连接,外链接(左连接、右连接、全连接),交叉连接大总结+附SQL JOINS图解[转]
    《大型网站技术架构》1.大型网站架构演练
  • 原文地址:https://www.cnblogs.com/fkissx/p/4501998.html
Copyright © 2011-2022 走看看