選擇排序 Selection Sort
選擇排序的基本思想是:每一趟在剩余未排序的若干記錄中選取關鍵字最小的(也可以是最大的,本文中均考慮排升序)記錄作為有序序列中下一個記錄。
如第i趟選擇排序就是在n-i+1個記錄中選取關鍵字最小的記錄作為有序序列中第i個記錄。
這樣,整個序列共需要n-1趟排序。
簡單選擇排序
一趟簡單選擇排序的操作為:通過n-i次關鍵字的比較,從n-i+1個記錄中選擇出關鍵字最小的記錄,並和第i個記錄交換之。
代碼如下:(假設記錄為整型,並且關鍵字為其本身)
Selection Sort
typedef int ElemType; void SelectSort(ElemType A[],int n) { ElemType temp; for(int i=1;i<n;++i) { int k=i-1; for(int j=i;j<n;++j) { if(A[j]<A[k]) { k=j; } } if(k!=i-1) { temp=A[i-1]; A[i-1]=A[k]; A[k]=temp; } } }
容易看出,簡單選擇排序中,所需進行記錄移動的操作次數較少,其最小值為“0”,最大值為3(n-1)。
然而,無論記錄的初始序列如何,所需進行的關鍵字間的比較次數相同,均為n(n-1)/2,因此,總的時間復雜度為O(n2)。
因為簡單選擇排序沒有利用上次選擇時比較的結果,所以造成了比較次數多,速度慢。如果能夠加以改進,將會提高排序的速度,所以出現了后面的樹形選擇排序和堆排序。
樹形選擇排序
樹形選擇排序(Tree Selection Sort),又稱錦標賽排序(Tournament Sort),是一種按照錦標賽思想進行選擇排序的方法。
首先對n個記錄的關鍵字進行兩兩比較,然后在其中[n/2](向上取整)個較小者之間再進行兩兩比較,如此重復,直至選出最小關鍵字的記錄為止。
這個過程可以用一棵有n個葉子結點的完全二叉樹表示。如圖中的二叉樹表示從8個關鍵字中選出最小關鍵字的過程:

8個葉子結點中依次存放排序之前的8個關鍵字,每個非終端結點中的關鍵字均等於其左、右孩子結點中較小的那個關鍵字,則根結點中的關鍵字為葉子結點中的最小關鍵字。
在輸出最小關鍵字之后,根據關系的可傳遞性,欲選出次小關鍵字,僅需將葉子結點中的最小關鍵字(13)改為“最大值”,然后從該葉子結點開始,和其左右兄弟的關鍵字進行比較,修改從葉子結點到根結點的路徑上各結點的關鍵字,則根結點的關鍵字即為次小值。

同理,可依次選出從小到大的所有關鍵字。
由於含有n個葉子結點的完全二叉樹的深度為[log2n]+1,則在樹形選擇排序中,除了最小關鍵字以外,每選擇一個次小關鍵字僅需進行[log2n]次比較,因此,它的時間復雜度為O(nlogn)。
但是,這種排序方法也有一些缺點,比如輔助存儲空間較多,並且需要和“最大值”進行多余的比較。
為了彌補,另一種選擇排序被提出——堆排序。
