五分鐘看懂一個高難度的排序:堆排序

預備知識:堆結構

堆是具備如下性質的徹底二叉樹:每一個結點的值都大於或等於其左右孩子結點的值,稱爲大頂堆;或者每一個結點的值都小於或等於其左右孩子結點的值,稱爲小頂堆。git

大頂堆

小頂堆

堆排序

堆排序(Heapsort)是指利用堆這種數據結構(後面的【圖解數據結構】內容會講解分析)所設計的一種排序算法。堆積是一個近似徹底二叉樹的結構,並同時知足堆積的性質:即子結點的鍵值或索引老是小於(或者大於)它的父節點。堆排序能夠說是一種利用堆的概念來排序的選擇排序。分爲兩種方法:github

  • 大頂堆:每一個節點的值都大於或等於其子節點的值,在堆排序算法中用於升序排列;算法

  • 小頂堆:每一個節點的值都小於或等於其子節點的值,在堆排序算法中用於降序排列;編程

堆排序的平均時間複雜度爲 Ο(nlogn)。數組

算法步驟

  1. 建立一個堆 H[0……n-1];數據結構

  2. 把堆首(最大值)和堆尾互換;編程語言

  3. 把堆的尺寸縮小 1,並調用 shift_down(0),目的是把新的數組頂端數據調整到相應位置;動畫

  4. 重複步驟 2,直到堆的尺寸爲 1。設計

來源:github.com/hustcc/JS-S…調試

算法演示

排序動畫過程解釋

  1. 首先,將全部的數字存儲在堆中

  2. 按大頂堆構建堆,其中大頂堆的一個特性是數據將被從大到小取出,將取出的數字按照相反的順序進行排列,數字就完成了排序

  3. 在這裏數字 5 先入堆

  4. 數字 2 入堆

  5. 數字 7 入堆, 7 此時是最後一個節點,與最後一個非葉子節點(也就是數字 5 )進行比較,因爲 7 大於 5 ,因此 7 和 5 交互

  6. 按照上述的操做將全部數字入堆,而後從左到右,從上到下進行調整,構造出大頂堆

  7. 入堆完成以後,將堆頂元素取出,將末尾元素置於堆頂,從新調整結構,使其知足堆定義

  8. 堆頂元素數字 7 取出,末尾元素數字 4 置於堆頂,爲了維護好大頂堆的定義,最後一個非葉子節點數字 5 與 4 比較,然後交換兩個數字的位置

  9. 反覆執行調整+交換步驟,直到整個序列有序

代碼實現

爲了更好的讓讀者用本身熟悉的編程語言來理解動畫,筆者將貼出多種編程語言的參考代碼,代碼所有來源於網上。

Go代碼實現

Java代碼實現

Python代碼實現

JavaScript代碼實現

若是你是iOS開發者,能夠在GitHub上 github.com/MisterBooo/… 獲取更直觀可調試運行的源碼。

你能夠在公衆號 五分鐘學算法 獲取更多排序內容。

相關文章
相關標籤/搜索