優先隊列與堆(二)

  • 索引優先隊列
    在很多應用中,允許用例引用已經進入優先隊列中的元素是很有必要的。做到這一點的簡單方法是給每個元素一個索引。另外,一個常見的情況是用例已經有了總量為N的多個元素,而且還可能同時使用了多個數組來存儲這些元素的信息。
    關聯索引的泛型優先隊列的API
    public class IndexMinPQ<Item extends Comparable<Item>>
    IndexMinPQ(int maxN) //創建一個最大容量為maxN的優先隊列,索引取值范圍為0~maxN-1
    void insert(int k, Item item) //插入一個元素,并與索引k關聯
    void change(int k, Item item) //將索引k的元素設為item
    boolean contains(int k) //是否存在索引為k的元素
    void delete(int k) //刪去索引k及其相關聯的元素
    Item min() //返回最小元素
    int minIndex() //返回最小元素索引
    int delMin() //刪除最小元素并返回它的索引
    boolean isEmpty() //優先隊列是否為空
    int size() //優先隊列的元素數量
    理解這種數據結構的一個較好的方式是把它看作一個能夠快速訪問其中最小元素的數組。事實上它還要更好——它可以快速訪問數組的一個特定子集的最小元素(即所有被插入的元素)。
    下面的用例調用了IndexMinPQ的代碼Multiway解決了多向歸并問題:將多個有序的輸入流歸并為一個有序的輸入流,且并不需要占用太多的內存。
    public class Multiway{
    public static void merge(In[] streams){
    int N = streams.length;
    IndexMinPQ<String> pq = new IndexMinPQ<String>(N);
    for(int i=0; i<N; i++){
    if(!streams[i].isEmpty())
    pq.insert(i, streams[i].readString());
    while(!pq.isEmpty()){
    StdOut.println(pq.min());
    int i = pq.delMin();
    if(!streams[i].isEmpty())
    pq.insert(i, streams[i].readStrings());
    }
    }
    public static void main(String[] args){
    int N = args.length;
    In[] streams = new In[N];
    for( int i=0; i<N; i++)
    streams[i] = new In(args[i]);
    merge(streams);
    }
    }

  • 堆排序
    堆排序可以分為兩個階段。在堆的構造階段,我們將原始的數組重新組織安排進一個堆中;然后在下沉排序階段,我們從堆中按遞減的順序取出所有元素并得到排序的結果。
    由N個給定的元素構造一個堆,當然可以從左至右的遍歷數組,用swim保證掃描指針左側的所有元素已經堆有序,但這樣做的話消耗的時間將與NlogN成正比,更加高效的辦法是從右至左用sink函數構造子堆。數組每個位置都是根結點了,sink()同樣適用于這些子堆。因此我們每次都只需要掃描一半的元素,并最后在位置1調用sink()方法。
    public static void sort(Comparable[] a){
    int N = a.length;
    for( int k =N/2; k>=1; k--)
    sink(a, k, N);
    while(N>1){
    exch(a, 1, N--);
    sink(a,q,N);
    }
    }
    這段代碼用sink()方法將a[1]到a[N]的元素排序。for循環構造了堆,然后用while循環將最大的元素a[1]和a[N]交換了位置并修復了堆,如此重復直至堆變空。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 數據機構與算法--索引優先隊列 圖片來自nullzx的博客園 索引優先隊列,用一個索引數組保存了元素在數組中的位置...
    sunhaiyu閱讀 2,754評論 0 0
  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經驗。 張土汪:刷leetcod...
    土汪閱讀 12,771評論 0 33
  • 數據結構與算法--優先隊列和堆排序 在某些數據處理的例子中,總數據量太大,無法排序(甚至無法全部裝進內存)。例如,...
    sunhaiyu閱讀 1,051評論 0 2
  • 那個盛夏之后, 你帶著將褪的青澀, 輕輕抽離枝丫, 帶著對朝霞的趨向, 在風中倏然一躍, 開始了飄漂的旅程。 我沒...
    茗香酒影閱讀 250評論 5 4
  • 讓世界擁有它的腳步,讓我保有我的繭。當潰爛已極的心靈再不想作一絲一毫的思索時,就讓我靜靜的回到我的繭內,以回憶為睡...
    趙小煥閱讀 282評論 0 0