排序演算法 堆排序

2021-09-08 23:48:19 字數 1373 閱讀 1383

前一陣子一直在寫排序的系列文章,最近因為一些事情耽擱了幾天,也穿插了幾篇其他類別的隨筆。今天還是回到排序上面來,善始善終,呵呵。

今天要介紹的也是一種效率很高的排序——堆排序

思想

堆排序,顧名思義,就是基於堆。因此先來介紹一下堆的概念。

堆分為最大堆和最小堆,其實就是完全二叉樹。最大堆要求節點的元素都要大於其孩子,最小堆要求節點元素都小於其左右孩子,兩者對左右孩子的大小關係不做任何要求,其實很好理解。有了上面的定義,我們可以得知,處於最大堆的根節點的元素一定是這個堆中的最大值。其實我們的堆排序演算法就是抓住了堆的這一特點,每次都取堆頂的元素,將其放在序列最後面,然後將剩餘的元素重新調整為最大堆,依次類推,最終得到排序的序列。

或者說,堆排序將所有的待排序資料分為兩部分,無序區和有序區。無序區也就是前面的最大堆資料,有序區是每次將堆頂元素放到最後排列而成的序列。每一次堆排序過程都是有序區元素個數增加,無序區元素個數減少的過程。當無序區元素個數為1時,堆排序就完成了。

本質上講,堆排序是一種選擇排序,每次都選擇堆中最大的元素進行排序。只不過堆排序選擇元素的方法更為先進,時間複雜度更低,效率更高。

圖例說明一下:(來自

具體步驟如下:

1 首先從第乙個非葉子節點開始,比較當前節點和其孩子節點,將最大的元素放在當前節點,交換當前節點和最大節點元素。

2 將當前元素前面所有的元素都進行1的過程,這樣就生成了最大堆

3 將堆頂元素和最後乙個元素交換,列表長度減1。由此無序區減1,有序區加1

4 剩餘元素重新調整建堆

5 繼續3和4,直到所有元素都完成排序

**

int adjust_heap(vector &v, int length, int i)

if (right < length && v[largest] < v[right])

if (i != largest)

else}}

int build_heap(vector &v, int length)

}int heap_sort(vector &v)

printline("

after sort:

",v);

}

分析堆排序的平均時間複雜度為o(nlogn),接近於最壞的時間複雜度。在最好情況下,時間複雜度為o(1).

排序演算法 堆排序

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

排序演算法 堆排序

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

排序演算法 堆排序

由於不經常使用,之前學習看過的演算法都給忘了。現在把他們寫下來,記錄下來,以方便以後查閱。本篇文章的 即為堆排序的 主函式中是對輸入檔案中的序列進行排序,並將結果輸出到乙個檔案中。這是一種形式類似於google codejam的測試方法。include include using namespace...