2-3 tree使用

來源:互聯網
上載者:User

標籤:des   style   class   blog   code   http   

The 2-3 tree is also a search tree like the binary search tree, but this tree tries to solve the problem of the unbalanced tree.

Imagine that you have a binary tree to store your data. The worst possible case for the binary tree is that all of the data is entered in order. Then the tree would look like this:

This tree has basically turned into a linked list. This is definitely a problem, for with a tree unbalanced like this, all of the advantages of the binary search tree disappear: searching the tree is slow and cumbersome, and there is much wasted memory because of the empty left child pointers.

浪費了儲存空間。

The 2-3 tree tries to solve this by using a different structure and slightly different adding and removing procedure to help keep the tree more or less balanced. The biggest drawback with the 2-3 tree is that it requires more storage space than the normal binary search tree.

The 2-3 tree is called such because the maximum possible number of children each node can have is either 2 or 3. This makes the tree a bit more complex, so I will try to explain as much as possible.

One big difference with the 2-3 tree is that each node can have up to two data fields. You can see the three children extending from between the two data fields.

一棵2-3樹具有下例性質:一個節點包含一個或者兩個關鍵碼;每個內部節點有2個子女(如果它包含一個關鍵碼),或者3個子女(包含2個關鍵碼);所有葉子節點在樹的同一層,因此樹總是高度平衡的。2-3樹每一個節點的左子樹中所有後繼節點的值都小於其父節點第一個關鍵碼的值;而中間子樹所有後繼節點的值都大於或等於其父節點第一個關鍵碼的值而小於第二個關鍵碼的值;如果有右子樹,則右子樹所有後繼節點都大於或等於其父節點第二個關鍵碼的值。2-3樹節點定義:struct node {int lkey,rkey,Numkeys;struct node *left,*center,*right;};(轉自http://baike.baidu.com/link?url=uLn9rjdrcao-itw7tbYdsExJCnmvVXaSxhjYrxSMq4azcDtc39EWYizn03ZUADfqCTq6MzjrASVaI7tRL5wI6K)

Thus, the tree is set up in the following manner:

  1. The node must always have a first field (data 1 in the diagram ), but not necessarily a second field (data 2). If both fields are present in a node, the first (or left) field of the node is always less than the second (or right) field of the node.
  2. Each node can have up to three child nodes, but if there is only one data field in the node, the node cannot have more than two children.
  3. The child nodes are set so that data in the first sub-tree is less than the first data field, the data of the second sub-tree is greater than the first data field and less than the second data field, and the data of the third sub-tree is greater than the second data field. If there is only one data field in the node, use the first and second children only.
  4. All leaf nodes appear on the last level.

Now, take a look at the implementation of a 2-3 tree:

class twoThreeTree {  public:    twoThreeTree(void);      // Constructor    ~twoThreeTree(void);     // Destructor     void add(int item);      // Adds an item    void search(int item);   //    Searches for an item  private:    twoThreeNode *root;      // Pointer to root node    // Private helper functions go here};class twoThreeNode {  public:    int firstData, secondData; // Two data fields    // The three child nodes    twoThreeNode *first, *second, *third;    // This next one is quite useful. It aids    // moving around the tree. It is a pointer    // to the parent of the current node.    twoThreeNode *parent;};

You can see that this tree, unlike the binary search tree or the heap tree, has no remove() function. It is possible to program a remove function, but it generally isn‘t worth the time or the effort.

This tree will be a bit harder to implement than the binary search tree just because of the complexity of the node. Still, the add() function algorithm isn‘tthat difficult, and a step-by-step progression through the algorithm helps enormously.

First, to add an item, find the place in the tree for it. This is very much the same as in the binary search tree: just compare and move down the correct link until leaf node is reached.

Once at the leaf node, there are three basic cases for the add() function:

  1. The leaf node has only one data item: this case is very simple. Just insert the new item after this item or shift the old item forward and insert the new item before the old one, depending on the situation.
     
  2. The leaf node is full and the parent node has only one data item: this case is also quite simple. Compare the three values: the two leaf node items and the new item. Choose the middle one and insert it in the parent node where appropriate.

    If the leaf node is the left child, shift the old data in the parent node to the right and insert the middle value in the parent node before the old data.Make sure to shift the pointers to the children in the parent node! If the leaf is the right child, just insert the middle value to the right of the old value in the parent node. The two left-over values from the comparison become two leaf nodes, one as the second child, and one as the first or third child depending on the situation.
     
  3. Both the leaf node and the parent node are full: this situation is the most complex of all. In the same manner as Case 2, promote the middle value of the leaf node. Then, continue doing the same thing with the parent node, and so on until the situation is resolved or the root node is reached. In this case, the middle value is promoted once again, except a new root node is created from the middle value and the two other values become the left and right subtrees of the new root. At the leaf node at which we began, the new level allows us to split the three initial values into a three node sub-tree of the parent node, and so on.

Doing a few small 2-3 trees by hand helps to understand this algorithm. Remember to check and hold to the rules governing the 2-3 tree! It can get ugly if they are ignored, especially with the last one.

Using some recursive helper functions as well as that miraculous parent variable will help ease the pain of programming this tree.

轉自:http://www.cprogramming.com/tutorial/computersciencetheory/twothree.html

發現前面說的比較囉嗦,看wikipedia一目瞭然http://en.wikipedia.org/wiki/2%E2%80%933_tree

2-3tree有兩種形式:

 

尋找:

在進行2-3樹的平衡之前,我們先假設已經處於平衡狀態,我們先看基本的尋找操作。

2-3樹的尋找和二叉尋找樹類似,要確定一個樹是否屬於2-3樹,我們首先和其跟節點進行比較,如果相等,則尋找成功;否則根據比較的條件,在其左中右子樹中遞迴尋找,如果找到的節點為空白,則未找到,否則返回。尋找過程如

插入

 

往一個2-node節點插入

往2-3樹中插入元素和往二叉尋找樹中插入元素一樣,首先要進行尋找,然後將節點掛到未找到的節點上。2-3樹之所以能夠保證在最差的情況下的效率的原因在於其插入之後仍然能夠保持平衡狀態。如果尋找後未找到的節點是一個2-node節點,那麼很容易,我們只需要將新的元素放到這個2-node節點裡面使其變成一個3-node節點即可。但是如果尋找的節點結束於一個3-node節點,那麼可能有點麻煩。

往一個3-node節點插入

往一個3-node節點插入一個新的節點可能會遇到很多種不同的情況,下面首先從一個最簡單的只包含一個3-node節點的樹開始討論。

只包含一個3-node節點

如,假設2-3樹只包含一個3-node節點,這個節點有兩個key,沒有空間來插入第三個key了,最自然的方式是我們假設這個節點能存放三個元素,暫時使其變成一個4-node節點,同時他包含四個子節點。然後,我們將這個4-node節點的中間元素提升,左邊的節點作為其左節點,右邊的元素作為其右節點。插入完成,變為平衡2-3尋找樹,樹的高度從0變為1。

節點是3-node,父節點是2-node

和第一種情況一樣,我們也可以將新的元素插入到3-node節點中,使其成為一個臨時的4-node節點,然後,將該節點中的中間元素提升到父節點即2-node節點中,使其父節點成為一個3-node節點,然後將左右節點分別掛在這個3-node節點的恰當位置。操作如:

 

節點是3-node,父節點也是3-node

當我們插入的節點是3-node的時候,我們將該節點拆分,中間元素提升至父節點,但是此時父節點是一個3-node節點,插入之後,父節點變成了4-node節點,然後繼續將中間元素提升至其父節點,直至遇到一個父節點是2-node節點,然後將其變為3-node,不需要繼續進行拆分。

 

 

根節點分裂

當根節點到位元組點都是3-node節點的時候,這是如果我們要在位元組點插入新的元素的時候,會一直查分到跟節點,在最後一步的時候,跟節點變成了一個4-node節點,這個時候,就需要將跟節點查分為兩個2-node節點,樹的高度加1,這個操作過程如下:

 

本地轉換

將一個4-node拆分為2-3node涉及到6種可能的操作。這4-node可能在跟節點,也可能是2-node的左子節點或者右子節點。或者是一個3-node的左,中,右子節點。所有的這些改變都是本地的,不需要檢查或者修改其他部分的節點。所以只需要常數次操作即可完成2-3樹的平衡。

性質

這些本地操作保持了2-3樹的平衡。對於4-node節點變形為2-3節點,變形前後樹的高度沒有發生變化。只有當跟節點是4-node節點,變形後樹的高度才加一。如所示:

 

轉自:http://www.cnblogs.com/yangecnu/p/3624443.html

關於2-3tree的一個ppt:http://www.docin.com/p-621379239.html

“B-樹”的“2-3樹”的題目,望前輩指導!!!
題目是: 
        從空樹開始,依次輸入20,30,50,52,60,68,70,畫出建立2-3樹的過程。並分別畫出刪除50和68後的B-樹狀態。 

        書上說:通常取最小值m=3(度數,階),此時B-樹中每個內部結點可以有2或3個孩子,故將這種3階的B-樹稱之為2-3樹。 

答案是:

答案給的是: 

1〉           [20] 

2〉           [20,30] 

3〉           [30] 
                /     \ 
            [20]   [50] 

4〉           [30] 
                /     \ 
            [20]   [50,52] 

5〉           [30,52] 
                /     |       \ 
          [20]   [50]   [60] 

6〉           [30,52] 
                /     |       \ 
          [20]   [50]   [60,68] 

7〉           [30,52,68] 
                /     |         \ 
          [20]   [50]     [60,70] 


8〉                 [52] 
                  /             \ 
              [30]         [68] 
              /     \         /     \ 
          [20][50][60][70]   

轉自:http://www.myexception.cn/arithmetic/256189.html

更多:

http://philoscience.iteye.com/blog/1401962

http://wenku.baidu.com/link?url=sV9mlLAfUhinrY_rU2FQ9o_azfspWVM9t2ez0DSHSzElUag4otXt_EcIG_Nga3jgJUrnFzeUDovyQApZz8j6QHqSBquNDEZIMss3FbW-ayi

相關文章

聯繫我們

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