1. 程式人生 > >演算法導論(9)

演算法導論(9)

線性時間排序

計數排序

          計數排序的前提是確定輸入範圍大小為0~k。在這個前提下,我們可以使用計數的方法對陣列進行排序,而不是使用比較。演算法思想如下:因為輸入陣列a[]中的元素範圍固定,因此可以使用一個大小為k的陣列c對a中的元素進行對映。

          1.如果輸入a為i,則使得c[i]++,表示元素i輸入的次數。對陣列a遍歷一次後,就會根據元素i的大小對映到陣列c中。

          2.對陣列c中的資料進行統計,算出在元素i之前有多少個比i小的資料。遍歷陣列c一次後,c[i]對應的是元素i在原陣列a中排列的第一個位置。

          3.使用位置關係陣列c,將a陣列逐一放到陣列b的相應位置中。遍歷a陣列一遍後,則此時b陣列為a陣列排序好的版本。

         因此演算法複雜度為o(n+k)

基數排序

       基數排序是將一個數分成幾個部分,分別從後往前將每部分排序,其他部分作為衛星資料連帶進行排序。

       對於整數而言,因為每一位的大小都是0~9,因此可以對每一次使用計數排序,從而對任意整數進行排序。

       假設需要排序的數位數d,因此如果對每一位都使用計數排序的話,總的時間複雜度為o(dn)

桶排序

      假設輸入是在區間[0~1)之間的隨機數,因此對n個這樣的隨機數分別放入乘以n後的桶中,接著對每一個桶都分別進行排序,然後按照順序將桶裡面的元素依次輸出則得到排序後的結果。

     因為對每個桶進行快速排序用時是分桶長度的平方,因此總的時間複雜度為


       進一步分析可得時間複雜度的期望為o(n)

全部程式碼如下:

  1. #include<stdio.h>
  2. #include<algorithm>
  3. #include<math.h>
  4. usingnamespace std;  
  5. int a[100];  
  6. int b[100];  
  7. int c[100];  
  8. //定義桶物件
  9. class Bucket{  
  10. public:  
  11.     float d;  
  12.     Bucket* next;  
  13.     Bucket(){}  
  14.     Bucket(float d){  
  15.         this->d=d;  
  16.     }  
  17. }*bucket[11];  
  18. //計數排序
  19. void conunting_sort(int *a, int *b, int k, int len){  
  20.     //初始化c陣列
  21.     for(int i=1; i<=k; i++)  
  22.       c[k]=0;  
  23.     //對a中元素出現次數的統計
  24.     for(int j=1; j<=len; j++)  
  25.       c[a[j]]++;  
  26.     //對c進行累加,得到位置資訊
  27.     for(int x=1; x<=k; x++)  
  28.       c[x]+=c[x-1];  
  29.     //使用位置資訊順序重建陣列
  30.     for(int y=len; y>=1; y--){  
  31.         b[c[a[y]]]=a[y];  
  32.         c[a[y]]--;  
  33.     }  
  34.     for(int z=1; z<=len; z++){  
  35.         a[z]=b[z];  
  36.     }  
  37. }  
  38. void exchange(char** str,int j){  
  39.     char* tmp;  
  40.     tmp=str[j];  
  41.     str[j]=str[j+1];  
  42.     str[j+1]=tmp;  
  43. }  
  44. //對基數排序中的每趟排序使用氣泡排序
  45. void char_bubble_sort(char** str,int d, int len){  
  46.     for(int i=0; i<len; i++)  
  47.       for(int j=0; j<len-1; j++){  
  48.         if(str[j][d]>str[j+1][d]){  
  49.             exchange(str,j);  
  50.         }  
  51.       }  
  52. }  
  53. //基數排序
  54. void radix_sort(char** str, int d, int len){  
  55.     for(int i=d-1; i>=0; i--){  
  56.         char_bubble_sort(str,i,len);  
  57.     }  
  58. }  
  59. //對桶排序的每趟使用氣泡排序
  60. void link_bubble_sort(Bucket* buck){  
  61.     Bucket *t,*tn;  
  62.     float s;  
  63.     for(Bucket* p=buck; p->next!=NULL; p=p->next){  
  64.         for(Bucket* q=buck; q->next->next!=NULL; q=q->next){  
  65.             if(q->next->d > q->next->next->d){  
  66.                 s=q->next->next->d;  
  67.                 q->next->next->d=q->next->d;  
  68.                 q->next->d=s;  
  69.             }  
  70.         }  
  71.     }  
  72. }  
  73. //桶排序
  74. void bucket_sort(float *a, int len){  
  75.     //分桶
  76.     for(int i=0; i<len; i++){  
  77.         Bucket *p;  
  78.         for(p=bucket[int(11*a[i])]; p->next!=NULL; p=p->next);  
  79.         p->next=new Bucket(a[i]);          
  80.     }  
  81.     //沒個桶內進行排序
  82.     for(int j=0; j<len; j++){  
  83.         link_bubble_sort(bucket[j]);  
  84.     }  
  85.     for(int k=0; k<len; k++){  
  86.         for(Bucket *q=bucket[k]; q->next!=NULL; q=q->next){  
  87.             printf("%.2f ",q->next->d);  
  88.         }  
  89.     }  
  90.     printf("\n");  
  91. }  
  92. int main(){  
  93.     int len;  
  94. //  char* str[16]={"COW","DOG","SEA","RUG","ROW","MOB","BOX","TAB","BAR","EAR","TAR","DIG","BIG","TEA","NOW","FOX"};
  95. /*  scanf("%d",&len); 
  96.     for(int i=1; i<=len; i++){ 
  97.         scanf("%d",&a[i]); 
  98.     } 
  99.     conunting_sort(a,b,len,len); 
  100.     for(int j=1; j<=len; j++){ 
  101.         if(j!=len) 
  102.             printf("%d ",a[j]); 
  103.         else 
  104.           printf("%d\n",a[j]); 
  105.     }*/
  106.     float a[11]={0.21,0.12,0.39,0.72,0.94,0.78,0.17,0.23,0.26,0.68,0.11};  
  107.     for(int z=0; z<11; z++){  
  108.         bucket[z]=new Bucket();  
  109.     }  
  110.     bucket_sort(a,11);  
  111. //  radix_sort(str,3,16);
  112. /*  for(int k=0; k<16; k++){ 
  113.         if(k!=15) 
  114.           printf("%s ",str[k]); 
  115.         else 
  116.           printf("%s\n",str[k]); 
  117.     } 
  118. */
  119.     return 0;  
  120. }