Date post: | 04-Jan-2016 |
Category: |
Documents |
Upload: | jonathan-perkins |
View: | 218 times |
Download: | 1 times |
Even MORE Balanced Trees Computing 2 COMP1927 15s1
OPTIMISATION BASED BALANCED TREES
So far we have seen local approaches Randomised trees…make poor performance
unlikely Splay trees…reasonable amortized performance BUT both still have O(n) worst case.
Ideally we want worst case to be O(log n) 2-3-4 trees…use varying-sized nodes to assist
balance red-black trees…isomorphic to 2-3-4, but with
binary nodes
2-3-4 TREES 2-3-4 trees have three kinds of nodes
2-nodes, with two children (same as normal BSTs)
3-nodes, two values and three children 4-nodes, three values and four children
2-3-4 TREES 2-3-4 trees are ordered similarly to BSTs
In a balanced 2-3-4 tree: all leaves are at same distance from the root 2-3-4 trees grow "upwards" from the leaves.
2-3-4 TREE IMPLEMENTATION:
typedef struct node *TreeLink;
struct node {
int order; // 2, 3 or 4
Item data[3]; // items in node
TreeLink child[4]; //links to subtrees
};
//New nodes are always order 2TreeLink newNode(Item item){ TreeLink n = malloc(sizeof(struct node)); n->order = 2; n->data[0] = it; n->child[0] = n->child[1] = NULL; return n;}
2-3-4 SEARCHING:
Item search(Tree t, Key k){
if(t == NULL) return NULL; int i, int diff;
int nItems = t->order-1;
for(i = 0; i < nItems; i++){
diff = compare(k,keyOf(t->data[i]);
if(diff <=0) break;
}
if(diff == 0) return t->data[i];
else return search(t->child[i],k);
}
2-3-4 INSERTION
Insertion into a 2-node or 3-node:
SPLITTING A NODE IN A 2-3-4 TREE:
Insertion into a 4-node (requires a split):
SPLITTING THE ROOT:
BUILDING A 2-3-4 TREE ... 7 INSERTIONS:
EXERCISE: 2-3-4 TREE INSERTION
Insert S then U into this 2-3-4 tree.
2-3-4 INSERTION ALGORITHM
Find leaf node where Item belongs (via search) if not full (i.e. order < 4)
insert Item in this node, order++ if node is full (i.e. contains 3 Items)
split into two 2-nodes as leaves promote middle element to parent insert item into appropriate leaf 2-node if parent is a 4-node
continue split/promote upwards if promote to root, and root is a 4-node
split root node and add new root
TOP DOWN INSERTION
To avoid propagation of splitting 4-nodes all the way up the tree we can use a top-down approach. Every time we encounter a 4-node on our way
down the search path for insertion, we split it.
EXERCISE: 2-3-4 TREE INSERTION
Insert S then U into this 2-3-4 tree using a top down approach
2-3-4 TREE SEARCHING COST ANALYSIS:
Worst case determined by height h2-3-4 trees are always balanced ⇒ height is
O(logN) worst case for height: all nodes are 2-
nodes same case as for balanced BSTs, i.e. h ≅ log2N
best case for depth: all nodes are 4-nodes balanced tree with branching factor 4, i.e. h ≅ log4N
SOME NOTES ON 2-3-4 TREES
Splitting the root is the only way depth increases.
One variation: why stop at 4? Allow nodes to hold up between M/2 and M
items. If each node is a disk-page, then we have a B-
tree (databases). Implement similar ideas using just BST nodes
→ red-black trees.
RED-BLACK TREES
Red-black trees are a representation of 2-3-4 trees using BST nodes. each node needs one extra value to encode link type but we no longer have to deal with different kinds of
nodes Link types:
red links ... combine nodes to represent 3- and 4-nodes
black links ... analogous to "ordinary" BST links (child links)
Advantages: standard BST search procedure works unmodified get benefits of 2-3-4 tree self-balancing (although
deeper)
RED BLACK TREES
Definition of a red-black tree: a BST in which each node is marked red or black no two red nodes appear consecutively on any
path Balanced red-black tree:
all paths from root to leaf have same number of black nodes
Insertion algorithm ensures that balanced trees remain balanced Prevents O(n) behaviour
REPRESENTING 3- AND 4-NODES IN RED-BLACK TREES:
RED BLACK LINKS
Colour allows us to distinguish links black = parent node is a "real"parent red = parent node is a 2-3-4 neighbour
EQUIVALENT TREES (ONE 2-3-4, ONE RED-BLACK):
RED-BLACK TREE IMPLEMENTATION:
typedef enum {RED,BLACK} Colour;
typedef struct Node *TreeLink;
struct Node {
Item data; // actual data
Colour colour; // colour of link to
// parent
TreeLink left; // left subtree
TreeLink right; // right subtree
} ;
EXERCISE
Draw the following 2-3-4 tree as an equivalent red-black tree
SOLUTION
RED BLACK TREE OPERATIONS
Search is same as standard BST Insertion is more complex than for standard
BSTs Need to balance only when we see 4-nodes
If a node has 2 red children it is part of a 4-node. Low overhead as there are not usually many 4-nodes
in a tree We can split 4-nodes in a top down manner,
splitting any 4 nodes on the search path down the tree during insertion
SPLITTING A 4-NODE
//Done while descending the tree
if(isRed(currTree->L) && isRed(currTree->R)){
currTree->colour = RED;
currTree->L-Colour = BLACK;
currTree->R->Colour = BLACK;
}
CHECKING SUBTREE AFTER INSERTION
Stage 1: in a red right subtree, and a successive leftward
red link
if(isRightSubtree &&isRed(currTree) &&
isRed(currTree->L)){
currTree = rotateR(currTree);
}
CHECKING SUBTREE AFTER INSERTION
Stage 2: two successive red links in same direction =
newly-created 4-node
if(isRed(currTree->L) && isRed(currTree->L->L)){
currTree = rotateR(currTree);
currTree->color = BLACK;
currTree->color = RED;
}
INSERTIONvoid Stinsert(Item item, ST st){
st->root = RBInsert(st->root,item,0);
st->root->colour = BLACK;
}
TreeLink RBInsert(TreeLink t, Item item, int inRightSubtree){
Key currKey = Key(item);
if(t == emptyTree){
//always part of an existing node
return new(item, emptyTree,emtyTree,RED);
}
if(isRed(currTree->left) && isRed(currTree->right)){
currTree->colour = RED;
currTree->left->Colour = BLACK;
currTree->right->Colour = BLACK;
}
INSERTIONif(less(currKey,Key(t->item))){ //insert in left
currTree->left = RBinsert(currTree->left, item, 0);
if(isRed(currTree && isRed(currTree->left) &&
inRightSubtree)
currTree = rotateR(currTree);
//Can’t be true if last if statement was true
if(isRed(currTree->left) &&
isRed(currTree->left_left)){
currTree = rotateR(currTree);
currTree->colour = BLACK;
currTree->right->colour = RED;
}
} else { //insert into right
SIMPLE EXAMPLE Insert keys 1,3,2
1 becomes the root 3 becomes the right child of 1 and has a red link
1 \ 3
2 becomes the left child of 3 and has a red link 1 \ 3 (3 is red and a right child and has a red left
child ) / so we rotate right at 3 2
SIMPLE EXAMPLE CONTINUED
After rotating at 3 we get this 1 (Now 1 has a red right and a red right
right link) \ so we rotate and change
colours 2 1 now has a red parent but 2 does not
\ 3
2 / \ 1 3
EXAMPLE OF SPLITTING
Suppose we wish to insert 4 into
2 / \ 1 3
2 is on the search path to insert 4 and has left and right red links so we split then keep inserting
2 / \ 1 3 \ 4
EXERCISE: RED/BLACK TREE INSERTION
Show the result of inserting the following values 8,4,6,2,3
RED-BLACK TREE COST ANALYSIS
Guaranteed O(log n) insertion, search and deletion Maximal height of a red-black tree
2 * log n
Yay!