二叉堆和堆排序

2021-07-31 14:16:39 字數 2697 閱讀 7985

(二叉)堆是乙個陣列,它可以近似看作完全二叉樹。樹上的每乙個節點對應陣列中的乙個元素。除了最底層,該樹是完全充滿的,而且是從左向右填充。

根據節點下標可以求出對應的子樹和雙親

parent(i)

return [i/2] //i表示陣列中的第幾個元素,[i/2]表示取整數

left(i)

return

2*i right(i)

return

2*i+1

二叉堆可分為最大堆和最小堆。堆頂元素(根節點元素)比其它節點元素都大的堆並且任何雙親節點都不小於子節點是最大堆,反之堆頂元素比其它節點元素都小,並且任何雙親節點都不大於子節點的堆是最小堆。

a是陣列

最大堆 a[parent(i)]>=a[i] (常用用於堆排序)

最小堆a[parent(i)]<=a[i] (常用於優先佇列)

堆的一些基本操作,比如建堆,調整堆,堆排序的時間複雜度是o(lg n)。堆的高度是lgn。

下面給出維護堆的偽**

max-heapify(a, i)

1 l=left(i) //獲取左子樹位置

2 r=right(i) //獲取右子樹位置

3if l<=a.heap-size and

a[l]>a[i]

4 largest=l;

5else largest=i

6if r<=a.heap-size and

a[r]>a[i]

7 largest=r

8if largest 不等於 i

9 exchange a[i] with a[largest]

max-heapify(a, largest) //遞迴呼叫,因為交換可能會破壞堆性質

我們從完全二叉樹的性質上來分析,字陣列a(|n/2|+1…n)中的元素都是樹的葉節點,豆哥葉節點都可以看成只包含乙個元素的堆。那麼建堆我們只需要從非a(|n/2|+1…n)的陣列元素開始呼叫建堆過程就可以了。下面給出偽**

build-max-heap(a)

1a.heap-size=a.length

2 for i=a[a.length/2] down to 1

3 max-heapify(a,i)

堆的用途之一是用於排序的堆排序。在建立完成最大堆(按公升序排序陣列,最小堆就是按降序排序陣列)之後,注意到整個陣列的 最大元素 總是在最大堆的第乙個,即a[0]。這時,如果我們拿走第乙個元素,放到陣列的最後乙個位置,然後對第乙個元素進行維護最大堆maxheapify,如此迴圈進行,便可完成整個陣列的排序。下面給出偽**

heapsort(a)

1 build-max-heap(a)

2 for i=a.length down to 2

3 exchange a[1] with a[i]

4a.heap-size--

5 max-heapify(a,1)

完整示例**

import org.junit.test;

/** * created by wunanliang on 2017/5/3.

* 堆資料結構

*/public

class

heapdemo ;

heapsort(arr);

for (int num : arr)

system.out.print(num + " ");

}/**

* 左子樹的位置

**@param parentindex 雙親節點位置

*@return

*/private

intleftchildindex(int parentindex)

/*** 右子樹的位置

**@param parentindex 雙親節點位置

*@return

*/private

intrightchildindex(int parentindex)

private

void

swap(int arr, int i, int j)

/*** 維護最大堆

**@param arr 陣列

*@param currentindex 當前位置

*@param length 陣列的長度

*/private

void

maxheapify(int arr, int currentindex, int length)

system.out.println("index:" + currentindex + "->" + arr[currentindex]);

}/**

* 建立最大堆

**@param arr

*/private

void

buildmaxheap(int arr)

private

void

heapsort(int arr) }}

參考資料

1《演算法導論 原書第3版》

2 堆排序以及最大優先佇列

新手講排序 堆排序 和 認識二叉堆

二叉堆是完全二叉樹或者是近似完全二叉樹 二叉堆滿足的二個特性 1.父節點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值 2.每個節點的左子樹和右子樹都是乙個二叉堆 都是最大堆或者是最小堆 當父節點的鍵值總是大於或等於任何乙個子節點的鍵值時為最大堆,總是小於或等於任何乙個子節點的鍵值時為最小堆...

二叉堆和堆排序的python實現

二叉堆本質上是一種完全二叉數 二叉堆建立 根據原陣列,然後從最後乙個非葉子節點開始,依次下沉,得到最後序列 二叉堆操作 圖比較麻煩就不畫了,可以參考這篇文章 二叉堆 1.二叉堆實現 儲存方式 利用陣列順序儲存 定位方法 利用陣列下標進行定位 父節點parent,左子樹 2 parent 1,右子樹 ...

序列化二叉堆與二叉堆排序

二叉堆分為最大堆與最小堆,一組不規則的完全二叉樹或者近完全二叉樹,可以通過調整稱為二叉堆。序列化 形成二叉堆通過下沉。插入元素通過上浮。排序 二叉堆的最大堆為父節點一定大於或者等於子節點,堆頂一定最大。如果最小堆的堆頂與最後乙個元素互動,那麼最後乙個元素一定最大。如果最後乙個元素不參加排序,那麼是一...