【基礎知識】之 堆排序(heap sorting)

來源:互聯網
上載者:User

Sorting

比較好的排序演算法可以把時間複雜度控制在O(n*log2n),最糟的情況是O(n2).

應該將sort當作一項基礎處理,因為對於很多問題,當其資料變成sorted items時,解決起來會很容易。

Stable Sorting

對於key相同的元素,有時我們需要保持它們原先的順序。但不幸的是,很少有快速演算法是stable的。不過,我們可以將元素的位置作為第二參考量,當元素a.key = b.key時,原先位置小的仍然排在前面。

選擇排序(selection sort)

選擇排序就是將一個item list分為兩部分,一部分是sorted,一部分是unsorted。每次都從unsorted的部分中取出最小的值,與索引位置i所在的元素進行交換,交換後,索引i加1;一直這樣下去,知道整個list完成排序。

交換一個元素所需的時間為O(1),但是在unsorted部分中尋找最小值則需要耗費O(n)的時間,這樣所有的元素排序一趟下來需要的時間為O(n2)。在這個過程中,如果能最佳化unsorted的部分,讓在其中尋找最小值的時間複雜度變小就可以最佳化整個選擇排序演算法,例如,如果把unsorted的部分改為balance tree結構的話,那麼在其中尋找最小值的時間複雜度將下降至O(log2n),那麼總的時間複雜度將下降至O(n*log2n)。

堆排序就是改進了資料結構的選擇排序演算法。

堆(heap)

堆是一種特別的結構,它的有序性比sorted order差,但是又比random order強。

例如最小堆(即某元素的父節點總比自己小,最大堆則正好相反

它儲存到數組中為:

 堆的特點是它是一個完全二叉樹,因此,它可以利用數組來方便地儲存其樹狀結構(而不需要像二叉搜尋樹一樣還需要額外的指標來維護樹結構)。

對於完全二叉樹,有如下特點:

①第l層的節點位於數組的2l-1至2l-1的位置

②對於節點k,其左孩子位於2k,右孩子位於2k+1,其父節點位於k/2

但它也有一些缺點,比如無法快速搜尋到一個某個節點,只能用廣搜一圈圈地搜,平均時間複雜度為O(n/2)

堆的構建

堆的構建採用冒泡的方式(ps:不是冒泡演算法的那個冒泡)

對於一個新的元素k,將其放在數組的最後,然後將它與自己的父節點進行比較,若它比自己的父節點小(假設構建的是最小堆),那麼將它與自己的父節點交換;一直這樣往上冒泡,直到有一個父節點比自己小或者冒到根節點為止。

PS:父節點的位置為k/2.

堆節點的摘除

在使用堆來做選擇排序時(也就是堆排序),會不停的摘掉堆的頂。

將堆的頂點摘除後,會留下一個洞,這時可以把數組的第n個(即最後一個元素)放置到頂部暫時充當根節點,然後將該節點和它的左孩子(2k)、右孩子(2k+1)進行比較,將三者中小的那個換到父節點的位置上;一直這樣下去直到堆重新穩定(即父節點是比左孩子、右孩子都小)。

ps:頂點摘除後,將最後一個元素暫移至root處,然後開始往下冒泡。

快速建立堆的小竅門

假設有n個元素,那麼第n個元素的父節點為n/2,也就是說從n/2以後的元素均為葉子節點。所以,在構建堆的時候,我們可以先填滿後n/2個元素。

例如:1945 1865 1963 1776 1492 1783 1918 2001 1941 1804,我們將5個元素從下往上填

現在開始從下往上填第六個元素

現在開始往下冒泡,k=5,故2k=10,2k+1=null,所以,對比 array[5]=1783 和 array[10]=1945,顯然1783 < 1945,故不需要進行交換。即在父節點、左孩子、右孩子中,父節點(1783)勝出。

接著,我們再從下往上填第七個元素

然後再進行父節點、左孩子、右孩子的遞迴比較

顯然9號元素1865勝出,因此將4號元素與9號元素進行交換,變成

交換後,k變成9,由於2k=18不存在,因此遞迴終止。

接著,我們再從下往上填寫第八個元素,即 2001

然後進行父節點、左孩子、右孩子的遞迴比較

6號元素1492勝出,因此將3號元素與6號元素換位

現在,k變成6,由於2k=12不存在,因此此次遞迴終止。

接下來再一次從下往上填寫第九個元素1941,遞迴比較換位後,再填寫第十個元素1804,再進行遞迴比較換位。最終的結果為:

整理,並畫成樹狀結構為:

堆排序

在建立完堆結構以後,進行堆排序的過程就是摘頂,調整堆結構,再摘頂,再調整堆結構,直到堆被摘完為止,這樣就可以得到一個有序序列。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.