【排序算法】選擇排序(C++實現)

選擇排序算法就是每一趟從待排序的記錄中選出關鍵字最小(最大)的記錄,順序放在已排好序的子文件的最後(最前),直到全部記錄排序完畢。常見的選擇排序有直接選擇排序(Selection Sort),堆排序(Heap Sort),平滑排序(Smooth Sort),笛卡爾樹排序(Cartesian Sort),錦標賽排序(Tournament Sort),循環排序(Cycle)。下面介紹前兩種:

(一)直接選擇排序

最差時間複雜度:O(n^2)
最優時間複雜度:O(n^2)
平均時間複雜度:O(n^2)
穩定性:不穩定

直接選擇排序(Selection Sort),這是一種簡單直觀的排序算法。它首先在未排序序列中找到最小(大)元素,存放到排序序列的其起始位置,然後再從剩餘未排序的序列元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到所有元素排序完畢。

算法示意圖:


實現代碼:

  1. void SelectSort(int *a, int len)  
  2. {  
  3.     for (int i=0; i<len-1; i++)  
  4.     {  
  5.         int k = i;  
  6.         int key = a[i];  
  7.         for (int j=i+1; j<len; j++)  
  8.         {  
  9.             if (a[j]<key)  
  10.             {  
  11.                 k = j;  
  12.                 key = a[j];  
  13.             }  
  14.         }  
  15.         if (k!=i)  
  16.             swap(a[i], a[k]);  
  17.     }  
  18. }  

(二)堆排序

最差時間複雜度:O(nlogn)
最優時間複雜度:O(nlogn)
平均時間複雜度:O(nlogn)
穩定性:不穩定

堆排序(Heap Sort),是利用堆這種數據結構所設計的一種排序算法。堆積是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子節點的鍵值或索引總是小於(或者大於)它的父節點。

通常堆是通過一維數組來實現的,在起始數組爲0的情形中,對於節點i:
其左子節點的下標爲 (2*i+1);
其右子節點的下標爲 (2*i+2);
其父節點的下標爲 floor((i-1)/2)。
在堆的數據結構中,堆中的最大值總是位於根節點。堆中定義一下三個操作:
1.最大堆調整(Max Heapify):在假定節點i的左右子節點爲根的兩顆二叉樹都是最大堆的前提下,確保父節點大於子節點,否則下降原父節點,最終使以i爲根的子樹成爲最大堆。
2.創建最大堆(Build Max Heap):將堆所有數據重新排序,對所有非葉子節點調用一次Max Heapify。

3.堆排序(Heap Sort):首先創建最大堆,然後依次將堆的根節點與末節點交換、剔除末節點、對根節點進行最大堆調整,直到堆中的節點數爲1,排序結束。

算法示意圖:


實現代碼:

  1. // 最大堆調整  
  2. void MaxHeapify(int *a, int i, int heapSize)  
  3. {  
  4.     int l = (i+1)*2-1;  
  5.     int r = (i+1)*2;  
  6.     int largest;  
  7.   
  8.     if (l<=heapSize && a[l]>a[i])  
  9.         largest = l;  
  10.     else  
  11.         largest = i;  
  12.   
  13.     if (r<=heapSize && a[r]>a[largest])  
  14.         largest = r;  
  15.   
  16.     if (largest!=i)  
  17.     {  
  18.         swap(a[i], a[largest]);  
  19.         MaxHeapify(a, largest, heapSize);  
  20.     }  
  21. }  
  22.   
  23. // 創建最大堆  
  24. void BuildMaxHeap(int *a, int len)  
  25. {  
  26.     for (int i=len/2-1; i>=0; i--)  
  27.     {  
  28.         MaxHeapify(a, i, len-1);  
  29.     }  
  30. }  
  31.   
  32. // 堆排序  
  33. void HeapSort(int *a, int len)  
  34. {  
  35.     BuildMaxHeap(a, len);  
  36.     for (int i=len-1; i>0; i--)  
  37.     {  
  38.         swap(a[0], a[i]);  
  39.         MaxHeapify(a, 0, i-1);  
  40.     }  
  41. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章