資料結構之簡單選擇排序和堆排序
阿新 • • 發佈:2021-06-26
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)穩定性:堆排序是一種不穩定的排序演算法。