資料結構堆以及堆排序的要點

2021-10-07 18:46:07 字數 2566 閱讀 4549

1 堆 

堆的重要性質:任意節點的值總是大於等於(或者小於等於)子節點的值

2  二叉堆 

二叉堆的邏輯結構是乙個完全二叉樹 也叫完全二叉堆

鑑於完全二叉樹的一些特性,二叉堆的底層(物理結構)一般用陣列實現 

索引 i 的規律,(n是元素的數量)

3 最大堆的建立

兩種方式: 1、自上而下的上慮      2、自下而上的下濾

上慮:把當前元素向上尋找其該在的位置,下濾:把當前元素向下尋找其該在的位置

對於大頂堆來說,上慮操作:當前元素與其父節點元素比較,如果小於父節點元素就進行交換位置,交換位置後再與其父節點元素進行比較,直到找到第乙個小於其父節點元素的位置。而下濾操作是:當前元素其子節點中較大的元素進行比較,如果小於子節點,就進行交換位置,交換位置後再次與其子節點較大的元素進行比較,直到找到第乙個大於其子節點元素的位置。因為下濾操作是當前點元素與子節點比較,所以對於葉子節點來說其沒有子節點,因此沒有下慮的必要,可以從第乙個非葉子節點開始進行下慮,即索引為(n/2-1)的元素開始。需要注意的是,下濾過程是父節點與子節點中相對較大的節點進行交換位置,即先從子節點中比較得出較大的子節點,再將較大的元素與父節點進行比較。

顯然:對於自上而下的上慮操作來說,每上濾乙個元素,所有已經上慮完成的元素可以構成乙個大頂堆,所以當上慮完成所有的元素的時候,整個堆會變成乙個大頂堆。而對於自下而上的下濾操作來說,每完成乙個下濾元素,該元素與左右子樹構成乙個大頂堆,以上圖為例,第一次下慮完成後,[13, 17] 構成大頂堆,第二次下慮完成後,[7,19,25]構成大頂堆,第三次下濾時,父節點元素2的左右子樹都已經時大頂堆了,元素2進行下濾時,其右子節點25要大於左子節點,所以元素2與右子節點25進行交換位置,當交換完成後,顯然[25,17,13]並沒有影響到左子樹的大頂堆結構,如果進行交換的元素是17,顯然右子樹[13,2]其大頂堆結構會被破環,同時[2,17,25]也不能構成大頂堆結構,顯然這樣交換是不合理的。這裡就解釋了為什麼自下而上的下濾操作可以構建堆結構,原因就是:每完成乙個下濾操作,該節點與其所有以下濾的左右子樹可以構成大頂堆,所以根節點下濾完成整個的堆結構完成構建過程。

4 堆的刪除操作(刪除堆頂元素)

以大頂堆為例,因為對於二叉堆結構來說,底層是陣列結構,刪除堆頂元素即陣列的第乙個元素,為減少陣列的元素移動,是將陣列的最後乙個元素放到陣列的第乙個位置即堆頂位置,顯然堆頂(根節點)的左右子樹仍然保持了其大頂堆的結構,這是只需要對堆頂元素進行下濾操作(當前元素向下尋找其合適的位置)即可重新構建其堆結構。

自上而下的上慮、自下而上的下濾  兩者效率比較(結論:自下而上的下濾操作效率要高

5 堆排序

排序原理,將陣列元素進行建堆,這裡以大頂堆為例,整個陣列完成大頂的建立後,將堆頂元素與陣列的最後乙個元素進行交換位置,在陣列的前n-1乙個元素再次進行建堆操作,完成建堆操作後再將堆頂元素與陣列的倒數第二個元素進行交換,這樣陣列的最後兩個元素就是整個陣列的最大的兩個元素,依次類推,直到完成整個陣列的排序。整個排序過程其實就是利用了堆定元素的刪除重新建堆的操作。

**實現

public static void main(string args) ;

heapsort(arr);

system.out.println(arrays.tostring(arr)); }

public static void heapsort(int arr)

system.out.println("----------------------");

while (size > 1)

} /**

* 下濾操作

* @param arr 下濾操作的陣列

* @param index 當前下濾操作元素在陣列中索引

* @param size 要要下了操作的陣列的元素個數(並不一定是對所有的陣列元素進行下濾,

* 可以是陣列的前面的一部分進行下濾)

*/private static void siftdown(int arr, int index, int size)

if (arr[bigger] > arr[index]) else

} }/**

* 交換位置

*/private static void swap(int i, int j, int arr)

/*** 返回較大的元素

*/private static int compare(int left, int right, int arr)

資料結構 堆以及堆排序

堆可以看作是一棵完全二叉樹,除最後一層外,每一層都是填滿的,最後一層從左到右依次填入 在堆上,對任意乙個結點來說,越接近頂部,權值就越大 一般指大頂堆 並且它的權值大於等於它所在子樹所有點的權值 我們把根結點權值大於等於樹中結點權值的稱為大根堆,小於等於樹種結點權值的稱為小根堆 下圖就是乙個大根堆的...

資料結構 堆以及堆排序

首先要明確一點,堆並不是我們直接寫好的,是需要建立堆,即根據一種演算法,把不是堆的一組資料變成大根堆或者小根堆,還是上述的圖我們可以知道這個堆的順序是100,90,85,72,71,65,79,52,56,45,58。當然,這個堆的順序存在多個,只要滿足根節點和孩子節點之間的關係就行,所以堆不是唯一...

堆(資料結構)及堆排序

這裡的堆是指一種資料結構 或資料結構屬性 非指堆記憶體。堆屬性用二叉樹來體現,具堆屬性的資料結構才可被叫做為堆。具堆屬性的資料結構滿足以下筆記的 順序 和 形狀 兩個條件。將某資料結構如陣列,將陣列的元素依次安排在二叉樹中的根結點 根結點的左孩子 根結點的右孩子位置之上,再將剩餘元素依次安排在根結點...