优先队列----堆
問題
打印機打印作業一般是放在隊列中的。如果按照先來先打印的順序,有一個100頁的打印任務,那么會讓后面短小的任務等待很長時間。更合理的做法也許是最后處理最耗時的打印任務,不管它是不是最后提交上來的。
在多用戶操作系統中,操作系統讓哪個程序使用CPU,是需要決定從隊列里面選擇的。一般做法是從隊頭獲得程序,分配一定時間的時間片。如果執行完,從隊列刪除;如果沒有執行完,插入隊尾。這樣處理的缺點是:一些很短小的程序需要花很長的時間才能執行完;有些比較重要的程序,不一定短小需要提前執行。
因此如果隊列中的每個任務都有一個優先級,先執行優先級高的,就可以解決問題了。這樣的隊列稱為優先隊列(priority queue)。
優先隊列定義
優先隊列是要很小的代價完成插入和刪除最小元素,兩個操作的數據結構。
二叉堆
通常情況下的堆是指二叉堆。思路是每次插入都將最小元素(如果業務要求是找最小元素),放置在根節點,用O(logN)時間完成。可以用O(1)的時間獲得最小元素。刪除最小元素的時候除了返回最小元素的值,還將選取新的最小元素,用O(logN)的時間。
結構性質
二叉堆是一棵被完全填滿的二叉樹,有可能最底層元素不滿,底層上的元素從左到右。(關鍵詞:滿二叉樹、從左到右)
堆序性質
對最小堆而言:每一個節點X>父節點的值。最大堆相反。
操作
操作的時間復雜度小于O(logN)
insert
deleteMin
decreaseKey
increaseKey
delete
buildHeap
優先隊列應用
選擇問題
輸入N個元素,查找第k小元素。解決思路1:將N個元素build一棵最小二叉堆,刪除k次,得到第k小元素。解決思路2:前k個元素build一棵最大二叉堆,后面的每個元素讀入的時候,與這里的最大元素比較,如果比最大元素小,則替換。
事件模擬
d堆
堆的分叉是d個,不僅僅是2個。有效降低堆的高度。實際中多用4-堆。
左勢堆
二叉堆不能很方便的合并,所以提出了左式堆。左式堆是一個二叉堆。不同點是堆中每隔一節點X,左兒子的零路徑長>=右兒子的零路徑長,記為:nlp(left)>=nlp(right)。整棵樹向左偏。
特殊操作
merge
時間復雜度 O(logN)
斜堆
二項隊列
每次操作的最壞情形是O(logN),而插入操作平均花費常數時間。
一個二項隊列是堆序的樹的集合(簡單的說就是樹的集合)。二項隊列中每一個高度的樹只有一顆。
這里有B0,B1,B2,B3,B4。Bk=Bk?1附加到另外一個Bk?1。
高度為k的二項樹恰好有2k個節點。我們就可以用二項隊列表示任意一個優先隊列。這與二進制表示一個數相同。例如6,的二進制是1101,B0,B2,B3三棵樹可以表示容量為6的優先隊列。
代碼任務
1 二叉堆的實現
2 左勢堆的合并
3 二項隊列的實現
總結
- 上一篇: N元语法模型的数据稀疏问题解决方法之一:
- 下一篇: SQL数据库被置疑后的恢复步骤(附详细图