堆、優先順序隊列和堆排序

來源:互聯網
上載者:User

堆結構是一種數組對象,其定義如下:它是完全二叉樹或者近似完全二叉樹。經常作為優先順序隊列,比如二叉樹優先順序隊列,四叉樹優先順序隊列。

n個關鍵字序列Kl,K2,…,Kn稱為(Heap),若且唯若該序列滿足如下性質(簡稱為堆性質):

  (1)ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n),當然,這是小根堆,大根堆則換成>=號。

        k(i)相當於二叉樹的非葉結點,K(2i)則是左孩子,k(2i+1)是右孩子

  若將此序列所儲存的向量R[1..n]看做是一棵完全二叉樹的儲存結構,則堆實質上是滿足如下性質的完全二叉樹:

  樹中任一非葉結點的關鍵字均不大於(或不小於)其左右孩子(若存在)結點的關鍵字。

 

優先順序隊列是不同於先進先出隊列的另一種隊列。
最大優先順序隊列,是這樣的一種隊列結構,它的內部存放著一系列的元素,每個元素都對應著一個最優級,
最大優先順序隊列不管各元素的入隊順序,在出隊時,總是對應優先順序最大的元素出隊。

最小優先順序隊列正好相反,不管入隊的順序,對應的權值最小的隊列元素出隊列。

優先順序隊列可以用二叉樹來實現,比如最大元素出隊列,只要在二叉樹中用常數時間取出最大值就可以了。取出了最大值之後,要繼續調整樹的狀態,使得第二大節點放入根節點。

堆排序

基本思想:對一組待排序記錄的關鍵字,首先建立一個堆,然後輸出最大(小)關鍵字,使得其餘的關鍵字重新構成一個堆,得到次大(小)的元素。這樣反覆執行,使得記錄成為一個有序序列,這個過程就稱為堆排序。由此可見,堆排序主要解決兩個問題:(1)如何使得一個無序的序列稱為一個有序的序列;(2)如何在輸出對頂元素之後,調整剩餘元素使之稱為一個堆。

調整堆的過程:從非終端節點開始,一直到最後節點。

//調整堆使之稱為大(小)頂堆void HeapAdjust(int *data,int s,int m){int j;int rc = data[s];for (j = 2 * s; j < m; j *= 2)//沿著關鍵字較大的孩子節點向下篩選{if (j < m && data[j] < data[j+1]){++j;//j是值較大元素的下標}if (!(rc<data[j])){break;}data[s] = data[j];s = j;//rc應插入在位置s上}data[s] = rc; //插入}

而建立堆只要從最後一個非葉子節點開始,向前逐步調整,這種調整的方法常稱為“篩選法”。

//堆排序void Heap_Sort(int* a,int n){int i = 0;for (i=n/2; i>0; i--)//把a建成大頂堆{HeapAdjust(a,i,n-1);}int temp;//臨時變數for (i=n-1; i>0; i--)  //將當前節點和最後一個資料交換{temp = a[0];a[0] = a[i];a[i] = temp;HeapAdjust(a,0,i-1);}}

堆排序的優點:平均時間複雜度是最壞時間複雜度都是O(nlogn),效率比較高。僅僅需要一個供交換用的輔助記錄大小空間。

缺點:不穩定,相同的資料元素在排序過程中可能移動位置。對於記錄數較少的排序不適合。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.