堆排序 選擇排序

2022-07-15 02:57:06 字數 2039 閱讀 6547

是一棵順序儲存完全二叉樹

其中每個結點的關鍵字都不大於其孩子結點的關鍵字,這樣的堆稱為小根堆

其中每個結點的關鍵字都不小於其孩子結點的關鍵字,這樣的堆稱為大根堆

舉例來說,對於n個元素的序列當且僅當滿足下列關係之一時,稱之為堆:

(1) ri <= r2i+1且 ri <= r2i+2 (小根堆)

(2) ri >= r2i+1且 ri >= r2i+2 (大根堆)

其中i=1,2,…,n/2向下取整; 

如上圖所示,序列r是乙個典型的小根堆。

堆中有兩個父結點,元素3和元素8。

元素3在陣列中以r[0]表示,它的左孩子結點是r[1],右孩子結點是r[2]。

元素8在陣列中以r[1]表示,它的左孩子結點是r[3],右孩子結點是r[4],它的父結點是r[0]。可以看出,它們滿足以下規律

設當前元素在陣列中以r[i]表示,那麼,

(1) 它的左孩子結點是:r[2*i+1];

(2) 它的右孩子結點是:r[2*i+2];

(3) 它的父結點是:r[(i-1)/2];

(4) r[i] <= r[2*i+1] 且 r[i] <= r[2i+2]。

首先,按堆的定義將陣列r[0..n]調整為堆(這個過程稱為建立初始堆),交換r[0]和r[n];

然後,將r[0..n-1]調整為堆,交換r[0]和r[n-1];

如此反覆,直到交換了r[0]和r[1]為止。

以上思想可歸納為兩個操作:

(1)根據初始陣列去構造初始堆(構建乙個完全二叉樹,保證所有的父結點都比它的孩子結點數值大)。

(2)每次交換第乙個和最後乙個元素,輸出最後乙個元素(最大值),然後把剩下元素重新調整為大根堆。

當輸出完最後乙個元素後,這個陣列已經是按照從小到大的順序排列了。

先通過詳細的例項圖來看一下,如何構建初始堆。

設有乙個無序序列 。

構造了初始堆後,我們來看一下完整的堆排序處理:

還是針對前面提到的無序序列  來加以說明。

增序排列,利用大根堆。

1

//注:陣列實現的堆中,第n個節點的左孩子的索引值是(2n+1),右孩子的索引是(2n+2)。

//其中,n為陣列下標索引值,如陣列中第1個數對應的n為0。23

void sift(rectype arr,int low,int

high)415

else

break; //

若根節點大於等於最大孩子的關鍵字,篩選結束16}

17 arr[i]=tmp;18}

1920

void heapsort(rectype arr,int n) //

arr[0...n-1]

2130 }

堆排序的平均時間複雜度為o(nlog2n),是一種不穩定的排序方法。

排序 選擇排序 選擇排序 堆排序

寫在前面 上傳github交換排序選擇排序 堆排序 選擇排序 顧名思義,我們就可以猜到,它是原則合適的元素放到合適的位置 從圖中,我們可以得到 1.用第乙個元素,和其他所有的元素進行比較,找出最小的,然後進行交換 2.然後進行,資料的遞增 3.直到資料全部有序 void selectsort int...

選擇排序 堆排序

選擇排序 selection sort 是一種簡單直觀的排序演算法。它的工作原理是每一次從待排序的資料元素中選出最小 或最大 的乙個元素,存放在序列的起始位置,直到全部待排序的資料元素排完。選擇排序是不穩定的排序方法 比如序列 5,5,3 第一次就將第乙個 5 與 3 交換,導致第乙個5挪動到第二個...

選擇排序 堆排序

堆排序 堆排序分為兩個過程 1 將原來無序的數列,轉化成堆序列 建初識堆的過程 2 輸出堆頂元素並調整建新堆的過程 資料結構偽 typeof sqlist heaptype void heapadjuisti heaptype h,int s int m for i h.length i 1 i c...