CS 2412 Data Structures Chapter 6 AVL Search Trees
The efficiency of binary search tree depends on the shape of the tree. • If an ordered or almost ordered sequence of data are inserted to a binary tree, then the search is not efficient. ( O ( n )). • If the inserted data is random, the tree is more efficient. • An idea binary search tree is a “balanced” tree, for that the search complexity is O (log n ). Data Structure 2016 R. Wei 2
Definition An AVL tree is a binary tree that either is empty or consists of two AVL subtrees, T L and T R , whose heights differ by no more than 1. Let H L , H R denote the height of T L , T R respectively, then | H L − H R | ≤ 1 . An AVL tree is also know as a height-balanced binary search tree. An AVL tree with H L = H R + 1 is called left high (LH), with H L = H R − 1 is called right high (RH), and with H L = H R is called equal (or even) high (EH). Data Structure 2016 R. Wei 3
Data Structure 2016 R. Wei 4
Balancing trees When a node is inserted into a tree or deleted from a balanced tree, the resulting tree may be unbalanced. Some rotating methods are used in AVL to balance the tree. 1. Left of left: a subtree of a tree that is left high has also become left high. 2. Right of right: a subtree of a tree that is right high has also become right high. 3. Right of left: a subtree of a tree that is left high has become right high. 4. Left of right: a subtree of a tree that is right high has become left high. Data Structure 2016 R. Wei 5
Data Structure 2016 R. Wei 6
Data Structure 2016 R. Wei 7
Left of left One simple case is that the lowest subtree is not balanced. This case needs a rotation to right. Another case is that the subtree is balanced, but the whole tree is not balanced. In this case, we need to rotate the root to right. And we also need to move the right subtree of the subtree as a left subtree of the old root. Right of right is similar. Data Structure 2016 R. Wei 8
Data Structure 2016 R. Wei 9
Data Structure 2016 R. Wei 10
Right of left Suppose the root is left high and the left tree is right high. To balance this tree, we need first to do a left rotation and then do a right rotation making the left node the new root. Suppose an internal node is left high and its left subtree is right high. First rotate the left subtree of the node. Now the node in a left of left situation, and we do the right rotation as the left of left case. Left of right is similar. Data Structure 2016 R. Wei 11
Data Structure 2016 R. Wei 12
Data Structure 2016 R. Wei 13
Algorithms for AVL AVL tree is a special kind BST. So some algorithms for BST can be used for AVL: such as search, retrieval, traversal etc. The insertion and deletion algorithm should be changed since the balance need to be checked constantly. Before insertion, AVL tree is balance. After inserting a node, a balance check may required. • If the original tree is EH, then no rotation is needed. • If the original tree is LH and the node is inserted to right subtree, or if the original tree is RH and the node is inserted to left subtree, then no rotation is needed. • Otherwise, we need to check if the resulting tree is balanced. Data Structure 2016 R. Wei 14
Data Structure 2016 R. Wei 15
If the root is LH and a node has been inserted to the left subtree which is now taller (higher). Then the following algorithm is called. The algorithm for right balance is similar to left balance (mirrors of each other). Data Structure 2016 R. Wei 16
rotateRight: Make left subtree new root and the right subtree of the left subtree the left subtree of the original root. Data Structure 2016 R. Wei 17
Rotate left is similar. Data Structure 2016 R. Wei 18
Deletion Deletion is similar to that in BST. First find out the node needs to be delete. If the node is a leaf, then simply delete it. If the node is not a leaf, then we need to find out a node which can replace the deleting node. Similar to insertion of AVL, we also need to check balance after deleting a node. For example, if the deleted node is at left subtree, and the original tree is RH, then we need to check if the left tree is shorter after deletion. Data Structure 2016 R. Wei 19
Data Structure 2016 R. Wei 20
Data Structure 2016 R. Wei 21
Data Structure 2016 R. Wei 22
Data Structure 2016 R. Wei 23
Delete left balance is similar. Data Structure 2016 R. Wei 24
Adjusting the balance factor After an insertion, we need to adjust the balance factors for the nodes. • If the root was EH before an insert, it is now high on the side in witch the insert was made. • If an insert was in the shorter subtree of a tree that was not EH, the root is now EH. • If an insert was in the higher subtree of a tree that was not EH, the root must be rotated. The balance factor need to adjust after deletion in a similar way. Data Structure 2016 R. Wei 25
Implement AVL in C #define LH +1 // Left High #define EH 0 // Even High #define RH -1 // Right High typedef struct node { void* dataPtr; struct node* left; int bal; //LH of EH or RH struct node* right; } NODE; typedef struct { int count; int (*compare) (void* argu1, void* argu2); NODE* root; } AVL_TREE; Data Structure 2016 R. Wei 26
AVL_TREE* AVL_Create (int (*compare) (void* argu1, void* argu2)) { AVL_TREE* tree; tree = (AVL_TREE*) malloc (sizeof (AVL_TREE)); if (tree) { tree->root = NULL; tree->count = 0; tree->compare = compare; } // if return tree; } // AVL_Create Data Structure 2016 R. Wei 27
bool AVL_Insert (AVL_TREE* tree, void* dataInPtr) { NODE* newPtr; bool forTaller; newPtr = (NODE*)malloc(sizeof(NODE)); if (!newPtr) return false; newPtr->bal = EH; newPtr->right = NULL; newPtr->left = NULL; newPtr->dataPtr = dataInPtr; tree->root = _insert(tree, tree->root, newPtr, &forTaller); (tree->count)++; return true; } // AVL_Insert Data Structure 2016 R. Wei 28
NODE* _insert (AVL_TREE* tree, NODE* root, NODE* newPtr, bool* taller) { if (!root) { root = newPtr; *taller = true; return root; } // if NULL tree if (tree->compare(newPtr->dataPtr, root->dataPtr) < 0) { root->left = _insert(tree, root->left, newPtr, taller); if (*taller) switch (root->bal) { case LH: // Was left high--rotate Data Structure 2016 R. Wei 29
root = insLeftBal (root, taller); break; case EH: // Was balanced--now LH root->bal = LH; break; case RH: // Was right high--now EH root->bal = EH; *taller = false; break; } // switch return root; } // new < node else { root->right = _insert (tree, root->right, newPtr, taller); if (*taller) switch (root->bal) Data Structure 2016 R. Wei 30
{ case LH: // Was left high--now EH root->bal = EH; *taller = false; break; case EH: // Was balanced--now RH root->bal = RH; break; case RH: // Was right high--rotate root = insRightBal (root, taller); break; } // switch return root; } // else new data >= root data return root; } // _insert Data Structure 2016 R. Wei 31
NODE* insLeftBal (NODE* root, bool* taller) { NODE* rightTree; NODE* leftTree; leftTree = root->left; switch (leftTree->bal) { case LH: // Left High--Rotate Right root->bal = EH; leftTree->bal = EH; root = rotateRight (root); *taller = false; break; case EH: // This is an error printf ("\n\aError in insLeftBal\n"); exit (100); case RH: // Right High-Requires double rightTree = leftTree->right; Data Structure 2016 R. Wei 32
switch (rightTree->bal) { case LH: root->bal = RH; leftTree->bal = EH; break; case EH: root->bal = EH; leftTree->bal = EH; break; case RH: root->bal = EH; leftTree->bal = LH; break; } // switch rightTree rightTree->bal = EH; root->left = rotateLeft (leftTree); root = rotateRight (root); *taller = false; } // switch return root; } Data Structure 2016 R. Wei 33
NODE* rotateLeft (NODE* root) { NODE* tempPtr; tempPtr = root->right; root->right = tempPtr->left; tempPtr->left = root; return tempPtr; } // rotateLeft The program for rotateRight is similar. Data Structure 2016 R. Wei 34
bool AVL_Delete (AVL_TREE* tree, void* dltKey) { bool shorter; bool success; NODE* newRoot; newRoot = _delete (tree, tree->root, dltKey, &shorter, &success); if (success) { tree->root = newRoot; (tree->count)--; return true; } // if else return false; } // AVL_Delete Data Structure 2016 R. Wei 35
NODE* _delete (AVL_TREE* tree, NODE* root, void* dltKey, bool* shorter, bool* success) { NODE* dltPtr; NODE* exchPtr; NODE* newRoot; if (!root) { *shorter = false; *success = false; return NULL; } // if if (tree->compare(dltKey, root->dataPtr) < 0) { root->left = _delete (tree, root->left, dltKey, shorter, success); Data Structure 2016 R. Wei 36
Recommend
More recommend