優先佇列 堆 二項佇列

2022-07-24 03:30:18 字數 3136 閱讀 9087

目錄四、 二項佇列的實現

**位址

​ 我們知道,左式堆每次操作的時間界是\(o(logn)\)。二項佇列支援合併、插入、刪除最小值,每次插入的平均時間為常數時間,而最壞時間是\(o(logn)\)。

​ 二項佇列:

結構**:

高度為0的二項樹是一棵單節點樹,例如b0

高度為k的二項樹\(b_k\)通過將一棵二項樹\(b_\)附接到另一棵二項樹\(b_\)的根上而構成。

結構描述:如上圖

​ 二項樹\(b_\)由乙個帶有兒子\(b_\),\(b_\),\(b_\),…,\(b_\)的根組成!高度為k的二項樹恰好有\(2^k\)個節點,而在深度\(d\)處的節點數是二項係數\(\binom\)。如果我們把堆序施加到二項樹上並允許任意高度最多一棵二項樹,那麼就能夠用二項樹的集合表示任意大小的優先佇列。例如大小為13的優先佇列可以用森林\(b_3\),\(b_2\),\(b_0\)表示。可以記作1101,它不僅使用二進位制表示了13的大小,而且也表達了這樣的事實:在上述表示中,\(b_3\),\(b_2\),\(b_0\)出現,而\(b_1\)沒有。

二項樹組成的森林根二進位制的關係:

數字13:森林表示為\(b_3\),\(b_2\),\(b_0\);二進位制記錄為1101。

數字10:森林表示為\(b_3\),\(b_1\);二進位制記錄為1010。

​ 二項佇列中,最小元可以通過森林中所有的的樹的根來找出。由於最多有\(logn\)棵不同的樹,因此找到最小元的時間可以為\(o(logn)\)。如果我們記住最小元,並且在每次操作時更新它,那麼可以直接操作最小元,時間為\(n\)。

​ 合併兩個二項佇列在概念上是乙個容易的操作。如下合併h1和h2。

合併**:

令\(h_3\)是新的二項佇列,由於\(h_1\)沒有高度為0的樹而\(h_2\)有,我們讓\(h_2\)中高度為0的樹作為\(h_3\)的一部分。然後將兩個高度為1的二項樹相加。

將\(h_1\)和\(h_2\)的高度為1的二項樹相加,讓大的根成為小的根的子樹,從而建立高度為2的二項樹。

現在存在3棵高度為2的樹,我們將合併其中2棵樹,建立高度為3的二項樹,這樣,就只存在一棵高度為2,一棵高度為3,一棵高度為0的樹組成的森林。

合併分析

​ 幾乎使用任意合理的實現方法合併2棵樹均花費常數時間,而總共存在\(o(lonn)\)棵二項樹,因此合併操作的最壞情形時間\(o(logn)\)。

關於時間界\(o(logn)\)

在n個節點組成的二項佇列森林中,每個高度有且只有一棵樹,很明顯,高度\(h = logn\),而合併操作本身花費常數時間,總個數\(o(logn)\)。很容得到以上時間界。

​ 關於插入,插入其實就是合併一棵高度為0的二項樹。關於插入的合併次數,如果元素將要插入的那個優先佇列中不存在的最小二項樹是\(b_i\),那麼執行時間與\((i+1)\)成正比

關於插入的時間界:

為什麼是\((i+1)\)的正比呢。假設:那麼插入乙個元素當作合併乙個高度為0的二項樹,記作\(c_0\);

\(i = 1\):森林中不存在\(b_1\),那麼最小樹則是\(b_0\),那麼只需要合併\(b_0\)和\(c_0\)就能得到一棵高度為1的樹,作為\(b_1\)。

\(i = 2\):森林中不存在$b_2 \(,那麼最小樹則是\)b_1 \(,第一次發生在\)b_0\(和\)c_0\(,得到\)c_1\(。第二次合併發生在\)b_1\(和\)c_1\(,得到\)b_2$。

依次類推,我們可以知道\(i\)就是需要合併的次數。而1是插入時間。得到上述時間描述。

​ 由於我們的二項佇列中所有的二項樹,均是堆序的。所以我們只需要比較所有樹的根節點,就能找到最小值。關鍵在於,我們刪除一棵高度為\(k\)的樹的根節點,那麼棵樹會降級為多棵樹,此時會打亂森林的順序,我們需要重新整理森林裡的樹,重新得到二項佇列。

刪除**:

刪除二項佇列h3中的最小值12,那麼由h3解體得到\(h3-2\),和原來的高度為0和1的樹得到的\(h3-2\)。

得到2個二項佇列:\(h3-1\),\(h3-2\)。現在要做的就是將這個佇列合併

根據上文的合併法則,得到\(h4\)。

刪除最小值本質上就是組建二項堆+合併二項堆。所以時間界依然是\(o(logn)\)。

關於這個時間界:

我們知道只要量級為改變,在大o模型中單純的加減是不會影響我們對於時間演算法的估計的。

​ 最重要的操作是deletemin和merge。deletemin需要快速找到最小值,因此需要一般樹的標準表示方法。該操作還要求各個兒子按照他們的子樹的大小排序。

​ 合併樹是我們需要將一棵樹作為另一棵樹的兒子被加到另一棵樹上。由於這顆心樹將是最大的子樹,因此,以大小遞減的方式保持這些子樹是最好的。

實現方法:

優先佇列之 二項堆

從以上定義,不難得到下面的結論 二項堆由一組二項樹所構成,這裡的二項樹需要滿足下列條件 1 h中的每個二項樹遵循最小堆的性質。2 對於任意非負整數k,在h中至多有一棵二項樹的根具有度數k。對於性質2,任意高度最多有一棵二項樹,這樣就可以用二項樹的集合唯一地表示任意大小的二項堆,比如13個結點的二項堆...

優先佇列《堆》

1.模型 兩個基本操作 insert等價enqueue deletemin刪除最小者 dequeue 2.簡單的實現 1 簡單鍊錶 遍歷刪除min或者排序刪除min 2 使用二叉查詢樹。反覆除去min會使得樹不平衡,並且bst還支援許多不需要的操作。3.二叉堆 優先佇列的實現普遍使用二叉堆,堆有兩個...

優先佇列 堆

印表機列印作業一般是放在佇列中的。如果按照先來先列印的順序,有乙個100頁的列印任務,那麼會讓後面短小的任務等待很長時間。更合理的做法也許是最後處理最耗時的列印任務,不管它是不是最後提交上來的。在多使用者作業系統中,作業系統讓哪個程式使用cpu,是需要決定從佇列裡面選擇的。一般做法是從隊頭獲得程式,...