1. 程式人生 > 其它 >資料結構之簡單選擇排序和堆排序

資料結構之簡單選擇排序和堆排序

1,簡單選擇排序

(1)演算法思想:每一趟從待排序的數列裡面選取最小的數,重複n-1次,因為最後還剩一個數不用在排序了。

(2)程式碼

 1 void SelectSort(int A[],int n)
 2 {
 3    for(int i=0;i<n-1;i++)
 4    {
 5          int min=i;    //假設最小元素在首部
 6          for(int j=i+1;j<n;j++)
 7           {
 8               if(A[j]<A[min]
 9                     min=j;       //
更新最小元素位置 10 } 11 if(min!=i) 12 swap(A[i],A[min]); //如果i位置元素不是最小值,則與最小值交換 13 } 14 }

(3)空間效率:空間效率為O(1)。

(4)時間效率:元素移動不會超過3(n-1)次,當對應表有序時,不需要移動。元素間比較次數與初始序列無關,始終是n(n-1)/2次,因此時間複雜度為O(n2)。

(5)穩定性:簡單選擇排序是一種不穩定的排序演算法。

2,堆排序

(1)演算法思想:首先將存放在L[n]中的n個元素建成初始堆,由於堆本身的特點(以大根堆為例),堆頂元素就是最大值。輸出堆頂元素,通常將堆頂元素送入堆底,此時根節點已不滿足大頂堆的性質,堆被破壞,將堆頂元素向下調整使其繼續保持大頂堆的性質,在輸出堆頂元素。如此重複,直到堆中僅剩一個元素為止。

(2)程式碼

 1 void BuildMaxHeap(int A[],int len)
 2 {
 3     for(int i=len/2;i>0;i--)          //反覆調整堆
 4      {
 5          HeadAdjust(A,i,len);
 6       }
 7 }
 8 
 9 void HeadAdjust(int A[],int k,int len) //函式將元素k為根的子樹進行調整
10 { 
11    A[0]=A[k];           //暫存子樹的根節點
12    for(i=2*k;i<=len;i*=2)     //沿key較大的子節點向下篩選
13 { 14 if(i<len&&A[i]<A[i+1]) 15 i++; //取key較大的子節點的下標 16 if(A[0]>=A[i]) 17 break; //篩選結束 18 else 19 { 20 A[k]=A[i]; //將較大的孩子替換雙親結點上 21 k=i; 22 } 23 } 24 A[k]=A[0]; //將篩選結點值放入最終位置 25 }

(3)調整次數與樹高有關,為O(h),關鍵字比較次數不超過4n,時間複雜度為O(n)。

(4)堆排序適合關鍵字較多的情況。

(5)空間效率:複雜度為O(1).

(6)時間效率:建堆時間為O(n),之後有n-1次向下調整操作,每次調整的時間複雜度為O(h),在最好、最壞、平均情況下,時間複雜度為O(nlog2n)。

(7)穩定性:堆排序是一種不穩定的排序演算法。