堆排序之 大頂堆

2021-08-29 01:44:01 字數 2155 閱讀 7719

堆的定義:

設有n個元素的序列

(1)(2)

解釋:如果讓滿足以上條件的元素序列(

建堆的步驟:

從最後乙個非終端結點開始往前逐步調整,讓每個雙親大於(或小於)子女,直到根節點為止。

注意:終端結點(即葉子)沒有任何子女,無需單獨調整。

建堆的具體做法:

(1)將原始序列轉換成完全二叉樹。

(2)從序號最大的非葉子節點開始遍歷,左右孩子中有比它大的,交換該節點和葉子的位置。

(3)父節點和較大的孩子節點交換後,新的父節點是穩定的,但是新的孩子節點可能不滿足大頂堆規則,而另一邊的孩子不會受影響。

(4)繼續對新孩子進行調整判斷,直至新孩子滿足規則,或者沒有新孩子為止。

建堆的一些性質:

(1)根據堆的性質,可以直接通過陣列索引對映堆中父子節點的關係。

(2)需要排序的陣列對應堆的層序遍歷。

(3)堆滿足一些公式:

左孩子 = arr[2i+1]

右孩子 = arr[2i+2]

大頂堆:arr[i]>=arr[2i+1] && arr[i]>=arr[2i+2]

小頂堆:arr[i]<=arr[2i+1] && arr[i]<=arr[2i+2]

最後乙個非葉子節點下標 = length/2-1

第乙個葉子節點下標 = length/2

最後乙個葉子節點 = length - 1

(4)堆調整是從最後乙個非葉子節點(下標時length / 2 - 1)開始。

(5)從小到大排序,調整為大頂堆。

關鍵:確定當前堆頂節點為最值後,如何將剩餘序列重新調整為堆?

方法:將當前堆頂節點與堆尾記錄交換,然後仿建堆動作重新調整,如此反覆直到排序結束。

基於初始堆進行堆排序的演算法步驟:

(1)堆的第乙個物件arr[0]具有最大的關鍵碼,將arr[0]與arr[length - 1]交換,把具有最大關鍵碼的物件交換到最後。

(2)再對前面的(length - 1) 個物件,使用堆的調整演算法,重新建立堆。結果具有次最大關鍵碼的物件又上浮到堆頂,即arr[0]位置。再交換arr[0]和arr[length - 2]。

(3)呼叫建堆的調整演算法對前面(length - 2)個物件重新調整。如此反覆,知道得到全部排序好的物件序列。

堆排序的演算法分析:

(1)時間效率:o(

(2)空間效率:o(1)

(3)穩定性:不穩定

(4)特點:對小檔案效果不明顯,但對大檔案有效。

public class getleastnumbers ;

heapsort(arr);

for (int i : arr) }

public static void heapsort(int a)

// 交換元素後,調整堆

for (int i=a.length-1; i>0; i--)

}/**

* 在陣列中交換兩個元素

* @param a 陣列

* @param index1 下標1

* @param index2 下標2

*/public static void swapreferences(int a, int index1, int index2)

/*** 調整堆的思路:從序號最大的非葉子節點開始便利,左右孩子中有比它大的,交換該節點和葉子的位置

* 父節點和較大的孩子節點交換後,新的父節點是穩定的,但是新的孩子節點可能不滿足大頂堆規則,而另一邊的孩子不會受影響,

* 所以要繼續對新孩子進行調整判斷,直至新孩子滿足規則,或者沒有新孩子為止

*/public static void heapadjust(int a, int i, int n)

if (tmp < a[child]) else

}a[i] = tmp; // 父節點元素給child

}public static int leftchild(int i)

}

堆排序(大頂堆)

ifndef maxheap define maxheap includeusing namespace std const int capacity 100 class maxheap void push const int data void initialize int a,int thesi...

堆排序詳解 大頂堆

堆的概念 堆是一顆順序儲存的完全二叉樹 每個結點的關鍵字都不大於其孩子結點的關鍵字,這樣的堆稱為小根堆 每個結點的關鍵字都不小於其孩子結點的關鍵字,這樣的堆稱為大根堆 對於n個元素的序列當且僅當下列關係之一的時候,稱之為堆 1 ri r2i 1 且 ri r2i 2 小根堆 2 ri r2i 1 且...

排序 堆排序 大根堆 大頂堆

1.小根堆 若根節點存在左子女則根節點的值小於左子女的值 若根節點存在右子女則根節點的值小於右子女的值。2.大根堆 若根節點存在左子女則根節點的值大於左子女的值 若根節點存在右子女則根節點的值大於右子女的值。3.結論 1 堆是一棵完全二叉樹 如果公有h層,那麼1 h 1層均滿,在h層連續缺失若干個右...