堆排序及經典用法 從100億個數中取出最大的1萬個
起源2023年計算機先驅獎獲得者、史丹福大學電腦科學系教授羅伯特·弗洛伊德(robert w.floyd)和威廉士(j.williams)在2023年共同發明了著名的堆排序演算法( heap sort )
「堆」定義
n個關鍵字序列kl,k2,…,kn稱為(heap),當且僅當該序列滿足如下性質(簡稱為堆性質):
(1) ki≤k2i且ki≤k2i+1 或(2)ki≥k2i且ki≥k2i+1(1≤i≤ n)
若將此序列所儲存的向量r[1..n]看做是一棵完全二叉樹的儲存結構,則堆實質上是滿足如下性質的完全二叉樹:樹中任一非葉結點的關鍵字均不大於(或不小於)其左右孩子(若存在)結點的關鍵字。 (即如果按照線性儲存該樹,可得到乙個不下降序列或不上公升序列)
【例】關鍵字序列(10,15,56,25,30,70)和 (70,56,30,25,15,10)分別滿足堆性質(1)和(2),故它們均是堆,其對應的完全二叉樹分別如小根堆示例和大根堆示例所示。
大根堆和小根堆:根結點(亦稱為堆頂)的關鍵字是堆裡所有結點關鍵字中最小者的堆稱為小根堆,又稱最小堆。根結點(亦稱為堆頂)的關鍵字是堆裡所有結點關鍵字中最大者,稱為大根堆,又稱最大堆。注意:①堆中任一子樹亦是堆。②以上討論的堆實際上是二叉堆(binary heap),類似地可定義k叉堆。
堆排序堆排序利用了大根堆(或小根堆)堆頂記錄的關鍵字最大(或最小)這一特徵,使得在當前無序區中選取最大(或最小)關鍵字的記錄變得簡單。
(1)用大根堆排序的基本思想
① 先將初始檔案r[1..n]建成乙個大根堆,此堆為初始的無序區
② 再將關鍵字最大的記錄r[1](即堆頂)和無序區的最後乙個記錄r[n]交換,由此得到新的無序區r[1..n-1]和有序區r[n],且滿足 r[1..n-1].keys≤r[n].key
③由於交換後新的根r[1]可能違反堆性質,故應將當前無序區r[1..n-1]調整為堆。然後再次將r[1..n-1]中關鍵字最大的記錄r[1]和該區間的最後乙個記錄r[n-1]交換,由此得到新的無序區r[1..n-2]和有序區r[n- 1..n],且仍滿足關係r[1..n-2].keys≤r[n-1..n].keys,同樣要將r[1..n-2]調整為堆。
直到無序區只有乙個元素為止。
(2)大根堆排序演算法的基本操作:
① 初始化操作:將r[1..n]構造為初始堆;
② 每一趟排序的基本操作:將當前無序區的堆頂記錄r[1]和該區間的最後乙個記錄交換,然後將新的無序區調整為堆(亦稱重建堆)。
注意:①只需做n-1趟排序,選出較大的n-1個關鍵字即可以使得檔案遞增有序。
②用小根堆排序與利用大根堆類似,只不過其排序結果是遞減有序的。堆排序和直接選擇排序相反:在任何時刻堆排序中無序區總是在有序區之前,且有序區是在原向量的尾部由後往前逐步擴大至整個向量為止
特點堆排序(heapsort)是一樹形選擇排序。堆排序的特點是:在排序過程中,將r[l..n]看成是一棵完全二叉樹的順序儲存結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關係(參見二叉樹的順序儲存結構),在當前無序區中選擇關鍵字最大(或最小)的記錄
堆排序與直接選擇排序的區別
直接選擇排序中,為了從r[1..n]中選出關鍵字最小的記錄,必須進行n-1次比較,然後在r[2..n]中選出關鍵字最小的記錄,又需要做n-2次比較。事實上,後面的n-2次比較中,有許多比較可能在前面的n-1次比較中已經做過,但由於前一趟排序時未保留這些比較結果,所以後一趟排序時又重複執行了這些比較操作。
堆排序可通過樹形結構儲存部分比較結果,可減少比較次數。
演算法分析
堆[排序的時間,主要由建立初始]堆和反覆重建堆這兩部分的時間開銷構成,它們均是通過呼叫heapify實現的。
堆排序的最壞時間複雜度為o(nlog2n)。堆序的平均效能較接近於最壞效能。
由於建初始堆所需的比較次數較多,所以堆排序不適宜於記錄數較少的檔案。
堆排序是就地排序,輔助空間為o(1),
它是不穩定的排序方法。
經典演算法 堆排序
堆排序是利用堆的性質來進行排序的乙個演算法。一 堆堆 英語 heap 是電腦科學中一類特殊的資料結構的統稱。堆通常是乙個可以被看做一棵樹的陣列物件。堆總是滿足下列性質 將根節點最大的堆叫做最大堆或大根堆,根節點最小的堆叫做最小堆或小根堆。常見的堆有二叉堆 斐波那契堆等。堆的定義如下 n個元素的序列當...
經典排序演算法 堆排序Heap sort
經典排序演算法 堆排序heap sort 堆排序有點小複雜,分成三塊 第一塊,什麼是堆,什麼是最大堆 第二塊,怎麼將堆調整為最大堆,這部分是重點 第三塊,堆排序介紹 第一塊,什麼是堆,什麼是最大堆 什麼是堆 這裡的堆 二叉堆 指得不是堆疊的那個堆,而是一種資料結構。堆可以視為一棵完全的二叉樹,完全二...
經典排序演算法 堆排序(Heap Sort)
首先堆是乙個完全二叉樹,但同時他具有這樣的要求 每乙個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆 每乙個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆。如下圖是乙個大頂堆 在此要補充乙個二叉樹的性質 二叉樹的某個節點下標為i,則它的左孩子的下標一定為2i,右孩子下標一定為2i 1。假如現...