2015-04-06 126 views
1

我正在構建一些數據的btree。一旦我構建btree(即插入所有元素),我不再插入或移除元素。然而,由此產生的b樹不是最優的,因爲如果我可以非常頻繁地得到每個節點的最大元素,那麼我的節點包含少於n個元素(問題變得更糟,大的n是)。這是從我的B樹的部分時,幾百個元素和ñ等於5的部分包含根節點和幾個最底層的節點 enter image description here如何最大化每個btree節點的元素數量

正如你可以看到不少的節點較少比5個元素。我的問題是: 有沒有一種方法可以在構建完成後「壓縮」btree,以便所有元素(除了可能是最底部的一些節點)都包含n元素。將要存儲在節點中的密鑰將是32位值,但我不能保證它們將以任何特定順序插入。

+0

我沒有時間閱讀這篇論文,但是你能否改變你構建btree的方式,使它在*施工過程中變得緊湊* http://www.sciencedirect.com/science/article/pii/0020019083900844 –

+0

這表明你可以在線性時間從頭開始構建一個緊湊的btree(在頂部的摘要中):http://cpsc.yale.edu/網站/默認/文件/文件/ tr167.pdf –

+0

那些文件談論插入按鍵「按順序」,我不能保證。我想我可以在第一個之後重建我的btree(因爲我會知道這個命令),但是這會佔用很多內存......如果沒有其他方法,我會這麼做...... – XapaJIaMnu

回答

1

如果因爲鍵/記錄沒有按鍵的順序交付獲得打包B樹的經典方法是不可行的,那麼基本上有兩種選擇:

  • 離線:建立從一個新的,裝B樹刮
  • 在線:通過使用節點相反分裂

建立一個新的B樹是簡單和快速的程序壓縮就地B樹,並且是可以做到的「幾乎」原地。唯一額外的空間需求包括一個頁面(或頁面緩衝區),用於btree的每個級別,以保持正在構建的新btree的正確脊柱。一旦它們被清空,舊樹的頁面可以被回收用於新樹。

該計劃通常被稱爲'金字塔'計劃或'自下而上'打包。不用說,它要求btree在打包過程中完全脫機,或者根據查詢的鍵將查詢分發到正確的樹(舊的或新的)。

在線壓縮採用基本相同的邏輯,只有細節有點不同,因爲密鑰(記錄)是從右邊的鄰居而不是從輸入來的。樹必須向上壓實一層一層,從底部,從最左邊的葉子:

  • 下拉從右邊鄰居
  • 水蛭鍵父節點分隔鍵,直到該節點全
  • 推右鄰居的新的最左邊的鍵向上作爲分隔
  • 做出正確的鄰居你的當前節點,沖洗和重複

兩種方案 - 包裝的建設和網上緊湊離子 - 可以使樹的右側脊上的節點充滿或甚至空着。如果這是不可取的,那麼可以通過在關卡的最後兩個節點之間重新分配鍵來修復它。這可以通過調用與正常btree操作中使用的相同的借用/平衡過程來完成。就像包裝和壓縮一樣,這種脊椎再平衡必須從下往上進行。即從最右邊的葉子到根部。

+0

感謝您的回答!你能否指點我一些關於在線方法的文獻?我無法真正找到任何東西,並使用拆分過程在非飽和節點的任何子節點上進行自上而下的編碼(並且重複直到樹不再變化)。關於離線方法,在我的問題的評論中,經典方法是兩篇論文中描述的方法嗎? – XapaJIaMnu

+0

谷歌搜索「B-tree批量加載」應該會爲您提供很多關於離線方法背後想法的信息,例如[Jens Dittrich的這個視頻](https://www.youtube.com/watch?v=HJgXVxsO5YU&index=1&list = LLYq4FK2x4AwjW2FxAZPydqA)。由Missie連接的[Rosenberg/Snyder論文](http://cpsc.yale.edu/sites/default/files/files/tr167.pdf)包含詳細的描述和僞代碼,但它極大地過度複雜化(至點根本沒有什麼幫助)。關鍵的一點是,更改btree節點會在樹中產生影響,這就是爲什麼您必須從底層開始逐級工作 – DarthGizka

+0

,以便完成的頁面不受冒泡變化的影響並保持與您的完全一樣打包他們。構建一個壓縮樹和一般批量加載之間唯一的區別在於您將所需的頁面利用率設置爲100%。算法的核心是:嘗試將傳入的密鑰追加到最右邊的頁面頁面(在驗證它大於樹的當前最大密鑰之後);如果最右側的頁面已滿,請添加一個空白頁面作爲新的最右側頁面,並嘗試以完全相同的方式**將下一個更高級別的**附加到**。 – DarthGizka

相關問題