幾種排序算法的C++實現——快速排序、堆排序、基數排序


排序算法是非常常見的面試筆試問題,考查的一個人的基本功,本文將一些排序做了C++的實現,就當是做個學習總結吧。

 

1、快速排序

  快速排序的中心是填坑法,取一個數(這里選取第一個數)作為基准數temp,從隊尾開始尋找第一個比基准數小的數a[j],交換a[j]和temp,然后隊首開始查找第一個比temp大的數a[i],交換之,遍歷的結果是當i>=j時,temp左邊的數都小於temp,后邊的數都大於temp,這個有點像歸並排序。最后利用遞歸調用完成排序,代碼如下:

 1 void QuickSort(int a[], int l,int r){
 2     if(l<r){
 3         int i=l,j=r,temp=a[l];
 4         while(i<j){
 5             while(i<j&&temp<=a[j])
 6                 --j;
 7             if(i<j)
 8                 a[i++]=a[j];
 9 
10             while(i<j&&temp>a[i])
11                 ++i;
12             if(i<j)
13                 a[j--]=a[i];
14         }
15         a[i]=temp;
16         QuickSort(a,l,i-1);
17         QuickSort(a,i+1,r);
18     }
19 }

  在筆試題中很多人選擇快速排序作為基礎算法對數組進行排序,一般認為快速排序是內部排序中最好的排序法之一,其平均時間復雜度為O(nlogn),但在已經完成排序的情況下,其最壞復雜度可以為O(n^2),且不穩定。

 

2、堆排序

  堆排序是基於完全二叉樹的排序方法,其中心思想是首先構造最大堆(或最小堆),即父節點總是大於其子節點,然后將堆化的數組a[0]與a[i]交換,即將最大數置於i位置,再將0—i的繼續堆化,重新選出最大的數於a[0],完成第一個排序。經過遍歷完成排序,其代碼為:

 1 //構造最大堆
 2 void MaxHeapFixDown(int a[], int i, int n){
 3     int j = 2*i+1;
 4     int temp = a[i];
 5     while(j<n){
 6         if(j+1<n&&a[j]<a[j+1])
 7             ++j;
 8         if(temp>a[j])
 9             break;
10         else{
11             a[i]=a[j];
12             i=j;
13             j=2*i+1;
14         }
15     }
16     a[i]=temp;
17 }
18 
19 //堆排序
20 void HeapSort(int a[], int n){
21     for(int i= n/2-1;i>=0;i--)
22         MaxHeapFixDown(a,i,n);
23     for(int i=n-1;i>=1;i--){
24         swap(a[i],a[0]);
25         MaxHeapFixDown(a,0,i);
26     }
27 }

  堆排序相對快速排序最大的有點時即便在最壞的情況下其復雜度也能達到O(nlogn),但也是不穩定排序.

 

3、基數排序

  基數排序中心思想是基數排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次類推,直到最高位。具體介紹可以參考http://www.cnblogs.com/Braveliu/archive/2013/01/21/2870201.html,代碼如下:

 1 //尋找數組中最大數的位數作為基數排序循環次數
 2 int KeySize(int a[], int n){
 3     int key = 1;
 4     for(int i=0;i<n;i++){
 5         int temp = 1;
 6         int r = 10;
 7         while(a[i]/r>0){
 8             temp++;
 9             r*=10;
10         }
11         key = (temp>key)?temp:key;
12     }
13     return key;
14 }
15 
16 //基數排序
17 void RadixSort(int a[], int n){
18     int key = KeySize(a,n);
19     int bucket[10][10]={0};
20     int order[10]={0};
21     for(int r = 1;key>0;key--,r*=10){
22         for(int i=0;i<n;i++){
23              int lsd = (a[i]/r)%10;
24              bucket[lsd][order[lsd]++]=a[i];
25         }
26 
27         int k = 0;
28         for(int i = 0;i<10;i++){
29             if(order[i]!=0){
30                 for(int j = 0;j<order[i];j++)
31                     a[k++]=bucket[i][j];
32             }
33             order[i]=0;
34         }
35     }
36 }

  基數排序是穩定算法,效率很高,其復雜度為O(nlog(r)m),其中r為所采取的基數,而m為堆數。但它只能用在整數的排序中,且需要借助一定的輔助空間。

 

 

*************************************************************************

先暫時跟新到這。。。。。

 

 

 

 

 




免責聲明!

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



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