排序算法匯總(C/C++實現)


前言:

    本人自接觸算法近2年以來,在不斷學習中越多地發覺各種算法中的美妙。之所以在這方面過多的投入,主要還是基於自身對高級程序設計的熱愛,對數學的沉迷。回想一下,先后也曾參加過ACM大大小小的校級賽、區域賽。沒什么驚天動地的獎項,最好的名次也就省三等獎。現在作為第一篇算法總結就拿常見的排序算法以我個人的理解,以及代碼實現跟大家簡單分享一下(排序算法如果一一羅列的話,不下十種。曾在圖書館的舊書架上看過一本近900頁的書,內容就是專門介紹排序算法)。

選擇排序(select)

選擇排序比較容易理解,每一次往后遍歷都是為了尋找“最小值”的下標。N次遍歷,時間復雜度為:O(n^2)

冒泡排序(bubble

冒泡排序也比較形象,理解為大氣泡不斷下沉,小氣泡往上冒。同樣往后進行n次遍歷,時間復雜度為:O(n^2)。跟選擇排序的區別:選擇排序屬於穩定排序,從初始狀態到排序完成過程中的每一次遍歷各元素前后位置“相對穩定”。而且,冒泡排序每一輪遍歷可能產生多次交換swap(),而選擇排序固定每一輪的遍歷都只進行一次交換swap()操作。

插入排序(insert)

插入排序可以理解為對撲克牌排序,原先拿到一手雜亂的牌,通過“插入”將所有牌排好序。

一般的插入排序時間復雜度同樣是:O(n^2),進行具體樣例測試時跟樣例數據的初始順序有關。

希爾排序(shell

希爾排序為進化版的插入排序,只因為其基於插入排序的思想上,加入步長”step”。一般讀者可能不知道希爾排序應用到大量數據的排序的高效,據研究的學者表明一般情況下希爾排序的排序時間復雜度降低為O(n^(3/2))

歸並排序(merge)

歸並排序是基於遞歸的思想進行的一種時間復雜度為:O(N*lgN)排序算法,不過其附加O(n)的空間輔助代價。理解好歸並排序后可以將其遞歸思想擴展應用到數列逆序數的求解問題上,這里不再展開。

快速排序(quick)

快速排序有多種實現方式,同樣是利用遞歸的思想,不斷將問題划分為具有相同性質的子問題進行求解。實現快速排序算法的平均時間復雜度為:O(N*lgN);快排的O(N*lgN)算法同樣通過拓展可以用於求無序數列的“第K大”元素。

堆排序(heap)

二叉堆,簡稱堆(heap)。一種非常奇妙的數據結構,是本人接觸過的算法當中最驚嘆的算法之一,僅僅利用數組就可以實現。在堆排序中,我們一般采用大根堆,時間復雜度O(N*lgN),排序效果較快排穩定,而且也不需要額外的空間存儲代價。

 


 

代碼實現部分(C/C++),本程序建議在codeblocks這款界面比較友好的IDE測試。

  1 /*
  2  *排序算法匯總(C/C++實現)
  3  */
  4 #include <cstdio>
  5 #include <cstring>
  6 //#define swap(x,y){x^=y;y^=x;x^=y;}
  7 #define swap(x,y){int temp=x;x=y;y=temp;}
  8 
  9 const int N = 10;
 10 
 11 void selectSort(int *a,int n){
 12     for(int i=0;i<n;i++){
 13         int min=i;
 14         for(int j=i+1;j<n;j++){
 15             if(a[j]<a[min]) min=j;
 16         }
 17         swap(a[i],a[min]);
 18     }
 19 }
 20 //something error!
 21 void bubbleSort(int *a,int n){
 22     for(int i=0;i<n;i++){
 23         for(int j=i;j<n;j++)
 24             if(a[j]<a[i]) swap(a[i],a[j]);
 25     }
 26 }
 27 void insertSort(int *a,int n){
 28     for(int i=1;i<n;i++){
 29         for(int j=i;j-1>=0&&a[j]<a[j-1];j--){
 30             swap(a[j],a[j-1]);
 31         }
 32     }
 33 }
 34 void shellSort(int *a,int n){
 35     //設定划分步長step
 36     int step=3;
 37     int h=1;
 38     while(h*step<n) h=h*step + 1;
 39     while(h>=1){
 40         for(int i=1;i<n;i++){
 41             for(int j=i;j-h>=0&&a[j]<a[j-h];j-=h)
 42                 swap(a[j],a[j-h]);
 43         }
 44         h /= step;
 45     }
 46 }
 47 void mergeSort(int *a,int p,int q,int *T){
 48     //[p,q)左閉右開
 49     if(p+1>=q) return;
 50     int m = p+(q-p)/2;
 51     //printf("m=%d\n",m);
 52     mergeSort(a,p,m,T);
 53     mergeSort(a,m,q,T);
 54     for(int i=p,x=p,y=m;i<q;){
 55         if( x<m && y<q && a[x]<a[y] || y>=q) T[i++]=a[x++];
 56         else T[i++]=a[y++];
 57     }
 58     for(int i=p;i<q;i++)
 59         a[i] = T[i];
 60 }
 61 void qSort(int *a,int p,int q){
 62     if(p>=q) return ;
 63     int i=p-1;
 64     for(int j=p;j<q;j++) if(a[j]<a[q]){
 65         i=i+1;
 66         swap(a[i],a[j]);
 67     }
 68     i=i+1;
 69     swap(a[i],a[q]);
 70 
 71     qSort(a,p,i-1);
 72     qSort(a,i+1,q);
 73 }
 74 
 75 void sink(int *a,int n,int k){
 76     while(2*k<=n){
 77         int j=2*k;
 78         if(j<n && a[j]<a[j+1]) j++;
 79         //if(a[j]<a[j+1]) j=j+1;
 80         if(a[k] > a[j]) break;
 81         swap(a[j],a[k]);
 82         k = j;
 83     }
 84 }
 85 void heapSort(int *a,int n){
 86     for(int k=n/2;k>=1;k--)
 87         sink(a,n,k);
 88     for(;n>1;){
 89         swap(a[1],a[n]);
 90         n--;
 91         sink(a,n,1);
 92     }
 93 }
 94 void pt(int *a,int s,int n){
 95     for(int i=s;i<n;i++)
 96         printf("%d ",a[i]);
 97     printf("\n");
 98 }
 99 int main(){
100     //printf("Hello world!\n");
101     int a[N]={2,1,-1,123,0,1,21,7,-10,1};
102     int b[N+1]={-999,2,1,-1,123,0,1,21,7,-10,1};
103     int T[N];
104     int c;
105     printf("請選擇一種排序算法:\n 1.選擇排序\n 2.冒泡排序\n 3.插入排序\n 4.希爾排序\n 5.歸並排序\n 6.快速排序\n 7.堆排序\n ----> ");
106     scanf("%d",&c);
107     switch(c){
108         case 1:
109             selectSort(a,N);
110             break;
111         case 2:
112             bubbleSort(a,N);
113             break;
114         case 3:
115             insertSort(a,N);
116             break;
117         case 4:
118             shellSort(a,N);
119             break;
120         case 5:
121             mergeSort(a,0,N,T);
122             break;
123         case 6:
124             qSort(a,0,N-1);
125             break;
126         case 7:
127             heapSort(b,N);
128             break;
129         default:
130             printf("選擇無效!");
131             return 1;
132     }
133     printf("輸出結果:\n");
134     if(c==7)
135         pt(b,1,N+1);
136     else
137         pt(a,0,N);
138 
139     return 0;
140 }

測試演示:

    

 

結語:

    以上排序算法尚不能涵蓋所有排序算法,比如基數排序,字符串排序等。本次排序算法分享內容就此打住,往后將持續更新。。。(因水平有限錯漏在所難免,望各朋友不吝批評指正^_^)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM