排序演算法 堆排序初探

2021-10-20 01:25:50 字數 2634 閱讀 6202

思想步驟

**實現

堆(heap)是一類特殊的資料結構的統稱。

堆通常是乙個可以被看做一棵完全二叉樹的陣列物件。

binary tree(二叉樹): 是樹的一種,主要的特點是二叉樹的所有節點最多只有兩個葉節點。除此之外沒有別的要求。

complete binary tree(完全二叉樹): 二叉樹的一種。在完全二叉樹當中,除了最後一層之外,所有層的節點都是滿的,且最後一層的節點也是從左到右的。優先填滿左邊的節點。

full binary tree(滿二叉樹): 二叉樹的一種。滿二叉樹的所有層,包括最後一層,都是滿的。也就是說,除了最後一層的節點外所有的節點都有兩個子節點。

heap(堆): 堆是一種樹。在樹的性質之外,堆要求節點按照大小(父節點比子節點大/父節點比子節點小)來排列。

binary heap(二叉堆): 二叉堆是近似於完全二叉樹的一種堆。除完全二叉樹的性質外,二叉堆還要求堆內元素按照大小排列。

min heap(最小堆): 最小的鍵值總是在最前面。換句話說,所有的父節點都比他們的子節點小。

max heap(最大堆): 最大的鍵值總是在最前面。換句話說,所有的父節點都比他們的子節點大。

堆排序(heapsort)是指利用堆這種資料結構所設計的一種排序演算法。

堆的性質保證了其根元素為最大或最小值;

每一次建立大/小頂堆,在堆頂取出最大/小值,把當前剩餘的最後乙個元素放到堆頂;

再次建立大/小頂堆,得到全部資料中第二大/小的值,取出,把當前剩餘的最後乙個元素放到堆頂;

重複上述步驟,直到全部元素都被取出。

假設乙個小根堆的左、右子樹都已是堆,並且根的元素名為root ,其左右子節點為left 和right ,這種情況下,有兩種可能:

(1) root<=left 並且 root<=right ,此時堆已完成;

(2)root>left 或者 root>right,此時 root 應與兩個子女中值較小的乙個交換,結果得到乙個堆,除非 root 仍然大於其新子女的乙個或全部的兩個。這種情況下,我們只需簡單地繼續這種將 「拉下來」的過程,直至到達某乙個層使它小於它的子女,或者它成了葉結點。

以公升序為例,需要不斷建立大頂堆

初始化大頂堆 (從倒數第二行的節點開始,從下往上、從右往左,這樣遍歷的順序保證了乙個小根堆的左、右子樹都已是堆)

假設乙個小根堆的左、右子樹都已是堆,並且根的元素名為root ,其左右子節點為left 和right ,這種情況下,有兩種可能:

(1) root<=left 並且 root<=right ,此時堆已完成;

(2)root>left 或者 root>right,此時 root 應與兩個子女中值較小的乙個交換,結果得到乙個堆,除非 root 仍然大於其新子女的乙個或全部的兩個。這種情況下,我們只需簡單地繼續這種將 「拉下來」的過程,直至到達某乙個層使它小於它的子女,或者它成了葉結點。

將陣列第乙個元素(即根節點)與陣列最後乙個元素交換(這時最後乙個元素成為了最大的)

重塑大頂堆

重複2.3.步驟,直至只剩下根節點

down——把i逐層向下比較,放到合適的地方;結合一定的呼叫前提,實現了把以i為堆頂的子堆變為大頂堆的功能。

void

down

(int array,

int i,

int size)

//如果父親不比兩個兒子都大

//那麼交換父親和兒子

//並且繼續往下檢視以剛剛的兒子為根的子堆

if(array[parent]

< array[child]

)//如果父親比兩個兒子都大,則大頂堆已經完成

//因為我們遍歷的順序保證了乙個子堆的左右子樹都已經是大頂堆

else

break;}

}

buildheap——將原無序陣列初始化為乙個大頂堆

void

buildheap

(int array,

int size)

比如,按照順序,先對倒數第二排的節點呼叫down函式,結果是,倒數第二排結合最後一排成為了乙個個大頂堆;

然後迴圈來到倒數第三排的節點,再呼叫down(由上述知,已經滿足了每個子堆的左右子樹都已經是大頂堆的前提),之後倒數第

三、二、一排共同組成了乙個個大頂堆;

以此類推,最終構建出了乙個真正的大頂堆。

heapsort——實現堆排序

void

heapsort

(int array,

int size)

}

main

int

main()

;int size =

sizeof

(array)

/sizeof

(int);

heapsort

(array, size)

;for

(int i =

0; i < size; i++

) cout << array[i]

<<

' ';

}

輸出結果

內部排序 堆排序初探

堆排序 heapsort 是指利用堆積樹 堆 這種資料結構所設計的一種排序演算法,它是選擇排序的一種。可以利用陣列的特點快速定位指定索引的元素。堆分為大根堆和小根堆,是完全二叉樹。大根堆的要求是每個節點的值都不大於其父節點的值,即a parent i a i 在陣列的非降序排序中,需要使用的就是大根...

排序演算法 堆排序

1 什麼是堆 首先它是一顆完全二叉樹,並且父結點的值大於子節點的值 最大堆 或父結點的值小於子結點的值 最小堆 小根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最小者的堆稱為小根堆,又稱最小堆。大根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最大者,稱為大根堆,又稱最大堆。2 堆...

排序演算法 堆排序

花了一晚上時間研究堆排序,這個排序困擾了哥很久,終於搞清楚了。一 堆的定義 1.父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值 2 每個結點的左子樹和右子樹都是乙個二叉堆 都是最大堆或最小堆 二 已知結點 i 則它的子結點 為2 i 1 與 2 i 2 父節點為 i 1 2 三 堆排序...