Presentation is loading. Please wait.

Presentation is loading. Please wait.

Balanced search trees: 2-3 trees.

Similar presentations


Presentation on theme: "Balanced search trees: 2-3 trees."— Presentation transcript:

1 Balanced search trees: 2-3 trees.
2-3 trees allow us to process ordered lists in more efficient way than binary trees with an ordering property. Recall that the worst case search efficiency in the later is O(N). All balanced trees guaranty at least O(logN) efficiency for the search operation. Definition: A 2-3 tree is a general tree which satisfies the following properties: Each node may store two data items. Each node may have three children. The second data item in any node may be empty, in which case sentinel value emptyFlag is stored there (assume emptyFlag := 0). If it is not empty, the first data item precedes the second one according to the specified ordering relationship. For each node, data in the first child precedes the first data item in the node; data in the second child follows the first data item, but precedes the second; data in the third child follows the data in the second data item. All leaf nodes are on the same level.

2 Example 2-3 tree Class Node23tree { Node23tree firstChild; Node23tree secondChild; Node23tree thirdChild; Node23tree parent; int firstItem; int secondItem; .... class methods follow }

3 Search in 2-3 trees Algorithm search23tree (tree, target, precedes)
Input: tree, a 2-3 tree; target, item sought; precedes, a comparator object Output: where, subtree containing the data; boolean found := false if (tree != null) { boolean atLeastOneItem := (firstItem != emptyFlag) boolean twoItems := (secondItem != emptyFlag) if (atLeastOneItem) if (firstItem = target) { item := firstItem found := true } else if (twoItems) if (secondItem = target) { item := secondItem found := true }

4 Search in 2-3 trees (contd.)
if (found || leafNode(tree) where := tree else if (atLeastOneItem) { if (precedes.lessThan(target, firstItem) search23tree (tree.firstChild, target, precedes) if (! twoItems) search23tree (tree.secondChild, target, precedes) if (precedes.lessThan(target, second Item) search23tree (tree.thirdChild, target, precedes) } else // the tree is emptry

5 Search in 2-3 trees (contd.)
Efficiency of the search operation: Because leaf nodes are at the same level (by definition), we have a full tree. The maximal path length in a full tree is log n + 1. Therefore, the efficiency of the search operation in 2-3 tree is guaranteed to be logarithmic. In the best and average cases, it is better than logarithmic, because nodes contain more than one data item.

6 Insertion in 2-3 trees Insert 250 and 850 in the following tree:
search for 250 stops here search for 850 stops here To find where to insert, we must first search for Search terminates in a node currently containing one item, 200. Therefore, we can insert 250 as a second item in that node. Search for 850 terminates in a node which already contains two items. We cannot create a new leaf node because this would violate the fullness of the tree. But we can split the node currently containing 750 and 800, into two “two” nodes (one containing 750, and the other containing 850). The middle value, 800, is recursively passed to the parent node, which may eventually have room to accommodate it.

7 Insertion example continued
700 800 The resulting tree:

8 Insertion in 2-3 tree (contd.)
In general, the following cases are possible when inserting an item in a 2-3 tree: Adding an item in a leaf node with room to accommodate the new item. Forcing a split with data being passed recursively up to their parent nodes until a node with one item is found to accommodate the passed data, or the root is split and the tree grows in height. The first item is inserted in the empty tree. Before we develop the insertItem method, we must say how the split of a node is performed.

9 The splitNode method Algorithm splitNode(tree, where, data, branch, addBranch, precedes) Input: tree, a 2-3 tree; where, a subtree to be split; data, item forcing the split; branch, if addBranch is true, branch is a subtree to be added as a child to a tree node that is splitting; if addBranch is false, has no well defined value upon entry to the method; addBranch, a Boolean variable which is true if branch is added to a splitting node, and false if a leaf node is being split; precedes, a comparator object defining the ordering relationship. Output: tree, a 2-3 tree eventually with a new root; where, a subtree which now contains only one item and has a sibling to its right.

10 The splitNode method (contd.)
/* case 1: splitting an external node / splitting the root node insert 700 parent, tree tree, where where */ if (where = tree) { Node23tree parent = new Node23tree() where.parent := parent parent.firstChild := where tree := parent } else parent := where.parent Node23tree sibling = new Node23tree () sibling.parent := parent

11 The splitNode method (contd.)
if (precedes.lessThan (data, where.firstItem)) { int middle := where.firstItem where.firstItem := data sibling.firstItem := where.secondItem where.secondItem := emptyFlag } else if (precedes.lessThan (data, where.secondItem)) { middle := data where.secondItem := emptyFlag } else { sibling.firstItem := data middle := where.secondItem where.secondItem := emptyFlag } /* the result in our example parent where sibling */

12 The splitNode method (contd.)
/* case 2: the splitting node is an internal node middle := splitting node where sibling branch splitted node */ if (addBranch) { int key := branch.firstItem if (precedes.lessThan(key, where.firstChild.firstItem)) { sibling.secondChild := where.thirdChild sibling.firstChild := where.secondChild where.thirdChild := NULL where.secondChild := where.firstChild where.firstChild := branch sibling.secondChild.parent := sibling sibling.firstChild.parent := sibling where.firstChild.parent := where }

13 else if (precedes.lessThan(key, where.secondChild.firstItem)) { sibling.secondChild := where.thirdChild sibling.firstChild := where.secondChild where.thirdChild := NULL where.secondChild := branch sibling.secondChild.parent := sibling sibling.firstChild.parent := sibling where.secondChild.parent := where } if (precedes.lessThan(key,where.thirdChild.firstItem)) { sibling.firstChild := branch sibling.firstChild.parent := sibling } else { sibling.secondChild := branch sibling.firstChild := where.thirdChild sibling.firstChild.parent := sibling }

14 /* the resulting tree parent 700 where sibling Now 700 must be accomodated in the parent node; if not possible, the parent node must split further. */ if (parent.firstItem = emptyFlag) { parent.firstItem := middle parent.firstChild := where parent.secondChild := sibling } else if (parent.secondItem = emptyFlag) { if (precedes.lessThan(parent.firstItem, middle)) { parent.secondItem := middle parent.thirdChild := sibling } else {

15 parent.secondItem := parent.firstItem
parent.firstItem := middle parent.thirdChild := parent.secondChild parent.secondChild := sibling } // end else else // split the parent node, which is an internal node splitNode(tree, parent, middle, sibling, true, precedes) // splitNode method end here

16 The insertItem method Algorithm insertItem(tree, newData, precedes)
Input: tree, a 2-3 tree; newData, item to be inserted; precedes, a comparator object defining the ordering relationship. Output: tree, a 2-3 tree with newData inserted Node23tree leaf = search23tree (tree, newData, precedes) if (leaf.FirstItem = emptyFlag) //insertion in an empty tree tree.firstItem := newData else { //add newData in the leaf; if not possible, call splitNode to split the leaf boolean twoItems := (leaf.secondItem != emptyFlag) if (twoItems) splitNode(tree, leaf, newData, leaf, false, precedes) else if (precedes.lessThan(leaf.firstItem, newData) leaf.secondItem := newData leaf.secondItem := leaf.firstItem leaf.firstItem := newData }


Download ppt "Balanced search trees: 2-3 trees."

Similar presentations


Ads by Google