0% found this document useful (0 votes)
15 views

6.red Black Trees and AVL Trees (Finalized)

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views

6.red Black Trees and AVL Trees (Finalized)

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 56

Red Black Trees and AVL Trees:

Red Black Trees is a balanced binary search


tree in which each node must have one extra bit to store the colour of that
node (either black or red). These colours are used to know whether the Tree is
balanced after insertions or deletions.

Rules for Red-Black Tree:

A node can have Either Red colour or Black Colour.


Root nodes always have Black Colour.

A red node can have only black children. Or, we can say that two adjacent
nodes cannot be Red in color.
If the node does not have a left or right child, then that node is said to be a
leaf node.
So, we put the left and right children below the leaf node known as nil.
The black depth or black height of a leaf node can be defined as the number
of black that we encounter when we move from the leaf node to the root
node.
One of the key properties of the Red-Black tree is that every leaf node
should have the same black depth.
In a red-black tree, every new node is inserted with the color red.
The insertion in the red-black tree is similar to the insertion operation in
a binary search tree.
But nodes are inserted with a color property.
After insertion operation, we need to check all the properties of the red-
black tree.
If all the properties are not satisfied, we perform the following operation
to make it a red-black tree.

Red-Black Tree properties:

Self-balancing binary search tree.


Each node must assign a colour, either black or red.
The root node is always black
Two red nodes can’t be the adjacent nodes.
Each leaf node must be black.
If a node is red, both its children must be black.
Every path from a given node to its descendant leaves contains the same
number of black nodes.

Advantages and Disadvantages of Red-Black Tree:


Note:

Every Red Black tree is a BST, But every BST need not be a Red
Black Tree
Every AVL tree is a Subset of Red black tree, But every red black tree
is not an AVL Tree.

Operations:

1. Insertion
2. Deletion

Insertion:

If the tree is empty, then we create a new node as a root node with the color
black.
If the tree is not empty, then we create a new node as a leaf node with a
color red.
If the parent of a new node is black, then exit.
If the parent of a new node is Red, then we have to check the color of the
parent's sibling of a new node.

 If the color is Black, then we perform rotations and recoloring.


 If the color is Red then we recolor the node.
 We will also check whether the parents' parent of a new node is the root
node or not; if it is not a root node, we will recolor and recheck the node.
Step: 1

The tree is checked to be empty so the first node added is a root and is coloured
black.

Step:2

Now, the tree is not empty so we create a new node and add the next integer
with colour red

Step:3

The nodes do not violate the binary search tree and RB tree properties;
hence we move ahead to add another node.The tree is not empty; we create a
new red node with the next integer to it. But the parent of the new node is not a
black coloured node,
The tree right now violates both the binary search tree and RB tree properties;
since parent’s sibling is NULL, we apply a suitable rotation and re-colour the
nodes.

Step:4

Now that the RB Tree property is restored, we add another node to the tree –

The tree once again violates the RB Tree balance property, so we check
for the parent’s sibling node colour, red in this case, so we just recolour the
parent and the sibling.

Step:5

We next insert the element 5, which makes the tree violate the RB
Tree balance property once again. And since the sibling is NULL, we apply
suitable rotation and recolour.
Step:6

Now, we insert element 6, but the RB Tree property is violated and


one of the insertion cases need to be applied −The parent’s sibling is red, so
we recolour the parent, parent’s sibling and the grandparent nodes since the
grandparent is not the root node.

Step:7

Now, we add the last element, 7, but the parent node of this new node
is red. Since the parent’s sibling is NULL, we apply suitable rotations (RR
rotation)

The final RB Tree is achieved.


Example:

#include <stdio.h>

#include <stdlib.h>

typedef struct Node

int data;

struct Node* left;

struct Node* right;

struct Node* parent;

int color; // 0 for Red, 1 for Black

} Node;

Node* createNode(int data) // Function to create a new Red-Black Tree


node {

Node* newNode = (Node*) malloc(sizeof(Node));

newNode->data = data;

newNode->left = newNode->right = newNode->parent = NULL;

newNode->color = 0; // Initially Red

return newNode;

Node* insertNode(Node* root, int data) // Function to insert a node into tree

{
Node* newNode = createNode(data);

if (root == NULL)

root = newNode;

else

Node* current = root;

Node* parent = NULL;

while (current != NULL)

parent = current;

if (data < current->data)

current = current->left;

else

current = current->right;

newNode->parent = parent;
if (data < parent->data)

parent->left = newNode;

else

parent->right = newNode;

return root;

void printTree(Node* root) // Function to print the Red-Black Tree

if (root != NULL)

printTree(root->left);

printf("%d (%s) \n", root->data, root->color ? "Black" : "Red");

printTree(root->right);

}
int main()

Node* root = NULL;

root = insertNode(root, 10);

root = insertNode (root, 20);

root = insertNode (root, 5);

root = insertNode (root, 15);

root = insertNode (root, 25);

printf("Red-Black Tree: \n");

printTree(root);

return 0;

Output:

Red-Black Tree:

5 (Red)

10 (Red)

15 (Red)

20 (Red)

25 (Red)
Deletion:
The deletion operation is more complex than insertion, as it requires not
only removing the node but also preserving the tree's balance and color properties.

Key Concepts:

A red-black tree has the following properties:

1. Every node is either red or black.


2. The root is always black.
3. Every leaf (NULL) is considered black.
4. If a node is red, both its children must be black.
5. Every path from a given node to its descendant leaves contains the
same number of black nodes.

The deletion operation on red black tree must be performed in such a way that it
must restore all the properties of a binary search tree and a red black tree. Follow
the steps below to perform the deletion operation on the red black tree

Firstly, we perform deletion based on the binary search tree properties.

Case 1: If either the node to be deleted or the node’s parent is red, just delete it.

Case 2: If the node is a double black, just remove the double black (double black
occurs when the node to be deleted is a black coloured leaf node, as it adds up the
NULL nodes which are considered black coloured nodes too)

Case 3: If the double black’s sibling node is also a black node and its child nodes
are also black in color, follow the steps below .
Remove double black:

Re-colour its parent to black (if the parent is a red node, it becomes black;
if the parent is already a black node, it becomes double black)
Recolor the parent’s sibling with red
If double black node still exists, we apply other cases.

Case 4:

If the double black node’s sibling is red, we perform the following steps

Swap the colors of the parent node and the parent’s sibling node.

Rotate parent node in the double black’s direction

Case 5:

If the double black’s sibling is a black node but the sibling’s child node
that is closest to the double black is red, follows the steps below −Swap the
colors of double black’s sibling and the sibling’s child in question Rotate the
sibling node is the opposite direction of double black (i.e. if the double black is
a right child apply left rotations and vice versa)

Apply case 6:

Case 6:

If the double black’s sibling is a black node but the sibling’s child node
that is farther to the double black is red, follows the steps below Swap the colors
of double black’s parent and sibling nodes

Rotate the parent in double black’s direction (i.e. if the double black is a
right child apply right rotations and vice versa)
Remove double black:

Change the color of red child node to black.

Deletion Example

Considering the same constructed Red-Black Tree above, let us


delete few elements from the tree.

Delete elements 4, 5, 3 from the tree.

To delete the element 4, let us perform the binary search deletion first.
After performing the binary search deletion, the RB Tree property is not disturbed,
therefore the tree is left as it is.

Then, we delete the element 5 using the binary search deletion

But the RB property is violated after performing the binary search deletion, i.e., all
the paths in the tree do not hold same number of black nodes; so, we swap the
colors to balance the tree.
Then, we delete the node 3 from the tree obtained

Applying binary search deletion, we delete node 3 normally as it is a leaf node.


And we get a double node as 3 is a black coloured node.

We apply case 3 deletion as double black’s sibling node is black and its child
nodes are also black. Here, we remove the double black, recolour the double
black’s parent and sibling.
Search:

The search operation in red-black tree follows the same algorithm as


that of a binary search tree. The tree is traversed and each node is compared
with the key element to be searched; if found it returns a successful search.
Otherwise, it returns an unsuccessful search.

Search in a red-black tree is similar to searching in a binary tree. It follows the


following steps:

1. First, we check if the root node is the desired node. If yes, return that.

2. If the value is less than the value of the root node, apply the search
function on its left child else, apply the search function on its right child.

3. Repeat the above steps unless we find the desired value or reach the tree's
end. We can check if it's the end of the tree if we encounter a None node.
In that case, return None or False.
Example:

#include <stdio.h>

#include <stdlib.h>

enum nodeColor {

RED,

BLACK

};

struct rbNode {

int data, color;

struct rbNode *link[2];

};

struct rbNode *root = NULL;

// Create a red-black tree

struct rbNode *createNode(int data) {

struct rbNode *newnode;

newnode = (struct rbNode *)malloc(sizeof(struct rbNode));

newnode->data = data;

newnode->color = RED;
newnode->link[0] = newnode->link[1] = NULL;

return newnode;

// Insert an node

void insertion(int data) {

struct rbNode *stack[98], *ptr, *newnode, *xPtr, *yPtr;

int dir[98], ht = 0, index;

ptr = root;

if (!root) {

root = createNode(data);

return;

stack[ht] = root;

dir[ht++] = 0;

while (ptr != NULL) {

if (ptr->data == data) {

printf("Duplicates Not Allowed!!\n");

return;
}

index = (data - ptr->data) > 0 ? 1 : 0;

stack[ht] = ptr;

ptr = ptr->link[index];

dir[ht++] = index;

stack[ht - 1]->link[index] = newnode = createNode(data);

while ((ht >= 3) && (stack[ht - 1]->color == RED)) {

if (dir[ht - 2] == 0) {

yPtr = stack[ht - 2]->link[1];

if (yPtr != NULL && yPtr->color == RED) {

stack[ht - 2]->color = RED;

stack[ht - 1]->color = yPtr->color = BLACK;

ht = ht - 2;

} else {

if (dir[ht - 1] == 0) {

yPtr = stack[ht - 1];

} else {
xPtr = stack[ht - 1];

yPtr = xPtr->link[1];

xPtr->link[1] = yPtr->link[0];

yPtr->link[0] = xPtr;

stack[ht - 2]->link[0] = yPtr;

xPtr = stack[ht - 2];

xPtr->color = RED;

yPtr->color = BLACK;

xPtr->link[0] = yPtr->link[1];

yPtr->link[1] = xPtr;

if (xPtr == root) {

root = yPtr;

} else {

stack[ht - 3]->link[dir[ht - 3]] = yPtr;

break;

}
} else {

yPtr = stack[ht - 2]->link[0];

if ((yPtr != NULL) && (yPtr->color == RED)) {

stack[ht - 2]->color = RED;

stack[ht - 1]->color = yPtr->color = BLACK;

ht = ht - 2;

} else {

if (dir[ht - 1] == 1) {

yPtr = stack[ht - 1];

} else {

xPtr = stack[ht - 1];

yPtr = xPtr->link[0];

xPtr->link[0] = yPtr->link[1];

yPtr->link[1] = xPtr;

stack[ht - 2]->link[1] = yPtr;

xPtr = stack[ht - 2];

yPtr->color = BLACK;
xPtr->color = RED;

xPtr->link[1] = yPtr->link[0];

yPtr->link[0] = xPtr;

if (xPtr == root) {

root = yPtr;

} else {

stack[ht - 3]->link[dir[ht - 3]] = yPtr;

break;

root->color = BLACK;

void deletion(int data) {

struct rbNode *stack[98], *ptr, *xPtr, *yPtr;

struct rbNode *pPtr, *qPtr, *rPtr;

int dir[98], ht = 0, diff, i;


enum nodeColor color;

if (!root) {

printf("Tree not available\n");

return;

ptr = root;

while (ptr != NULL) {

if ((data - ptr->data) == 0)

break;

diff = (data - ptr->data) > 0 ? 1 : 0;

stack[ht] = ptr;

dir[ht++] = diff;

ptr = ptr->link[diff];

if (ptr->link[1] == NULL) {

if ((ptr == root) && (ptr->link[0] == NULL)) {

free(ptr);

root = NULL;
} else if (ptr == root) {

root = ptr->link[0];

free(ptr);

} else {

stack[ht - 1]->link[dir[ht - 1]] = ptr->link[0];

} else {

xPtr = ptr->link[1];

if (xPtr->link[0] == NULL) {

xPtr->link[0] = ptr->link[0];

color = xPtr->color;

xPtr->color = ptr->color;

ptr->color = color;

if (ptr == root) {

root = xPtr;

} else {

stack[ht - 1]->link[dir[ht - 1]] = xPtr;

}
dir[ht] = 1;

stack[ht++] = xPtr;

} else {

i = ht++;

while (1) {

dir[ht] = 0;

stack[ht++] = xPtr;

yPtr = xPtr->link[0];

if (!yPtr->link[0])

break;

xPtr = yPtr;

dir[i] = 1;

stack[i] = yPtr;

if (i > 0)

stack[i - 1]->link[dir[i - 1]] = yPtr;

yPtr->link[0] = ptr->link[0];

xPtr->link[0] = yPtr->link[1];
yPtr->link[1] = ptr->link[1];

if (ptr == root) {

root = yPtr;

color = yPtr->color;

yPtr->color = ptr->color;

ptr->color = color;

if (ht < 1)

return;

if (ptr->color == BLACK) {

while (1) {

pPtr = stack[ht - 1]->link[dir[ht - 1]];

if (pPtr && pPtr->color == RED) {

pPtr->color = BLACK;

break;

}
if (ht < 2)

break;

if (dir[ht - 2] == 0) {

rPtr = stack[ht - 1]->link[1];

if (!rPtr)

break;

if (rPtr->color == RED) {

stack[ht - 1]->color = RED;

rPtr->color = BLACK;

stack[ht - 1]->link[1] = rPtr->link[0];

rPtr->link[0] = stack[ht - 1];

if (stack[ht - 1] == root) {

root = rPtr;

} else {

stack[ht - 2]->link[dir[ht - 2]] = rPtr;

dir[ht] = 0;

stack[ht] = stack[ht - 1];


stack[ht - 1] = rPtr;

ht++;

rPtr = stack[ht - 1]->link[1];

if ((!rPtr->link[0] || rPtr->link[0]->color == BLACK) &&

(!rPtr->link[1] || rPtr->link[1]->color == BLACK)) {

rPtr->color = RED;

} else {

if (!rPtr->link[1] || rPtr->link[1]->color == BLACK) {

qPtr = rPtr->link[0];

rPtr->color = RED;

qPtr->color = BLACK;

rPtr->link[0] = qPtr->link[1];

qPtr->link[1] = rPtr;

rPtr = stack[ht - 1]->link[1] = qPtr;

rPtr->color = stack[ht - 1]->color;

stack[ht - 1]->color = BLACK;


rPtr->link[1]->color = BLACK;

stack[ht - 1]->link[1] = rPtr->link[0];

rPtr->link[0] = stack[ht - 1];

if (stack[ht - 1] == root) {

root = rPtr;

} else {

stack[ht - 2]->link[dir[ht - 2]] = rPtr;

break;

} else {

rPtr = stack[ht - 1]->link[0];

if (!rPtr)

break;

if (rPtr->color == RED) {

stack[ht - 1]->color = RED;

rPtr->color = BLACK;

stack[ht - 1]->link[0] = rPtr->link[1];


rPtr->link[1] = stack[ht - 1];

if (stack[ht - 1] == root) {

root = rPtr;

} else {

stack[ht - 2]->link[dir[ht - 2]] = rPtr;

dir[ht] = 1;

stack[ht] = stack[ht - 1];

stack[ht - 1] = rPtr;

ht++;

rPtr = stack[ht - 1]->link[0];

if ((!rPtr->link[0] || rPtr->link[0]->color == BLACK) &&

(!rPtr->link[1] || rPtr->link[1]->color == BLACK)) {

rPtr->color = RED;

} else {

if (!rPtr->link[0] || rPtr->link[0]->color == BLACK) {

qPtr = rPtr->link[1];
rPtr->color = RED;

qPtr->color = BLACK;

rPtr->link[1] = qPtr->link[0];

qPtr->link[0] = rPtr;

Ptr = stack[ht - 1]->link[0] = qPtr;

rPtr->color = stack[ht - 1]->color;

stack[ht - 1]->color = BLACK;

rPtr->link[0]->color = BLACK;

stack[ht - 1]->link[0] = rPtr->link[1];

rPtr->link[1] = stack[ht - 1];

if (stack[ht - 1] == root) {

root = rPtr;

} else {

stack[ht - 2]->link[dir[ht - 2]] = rPtr;

break;

}
}

ht--;

// Print the inorder traversal of the tree

void inorderTraversal(struct rbNode *node) {

if (node) {

inorderTraversal(node->link[0]);

printf("%d ", node->data);

inorderTraversal(node->link[1]);

return;

// Driver code

int main() {

int ch, data;

while (1) {
printf("1. Insertion\t2. Deletion\n");

printf("3. Traverse\t4. Exit");

printf("\nEnter your choice:");

scanf("%d", &ch);

switch (ch) {

case 1:

printf("Enter the element to insert:");

scanf("%d", &data);

insertion(data);

break;

case 2:

printf("Enter the element to delete:");

scanf("%d", &data);

deletion(data);

break;

case 3:

inorderTraversal(root);

printf("\n");
break;

case 4:

exit(0);

default:

printf("Not available\n");

break;

printf("\n");

return 0;

Output:

1. Insertion 2. Deletion

3. Traverse 4. Exit

Enter your choice:1

Enter the element to insert:10

1. Insertion 2. Deletion

3. Traverse 4. Exit

Enter your choice:1


Enter the element to insert:5

1. Insertion 2. Deletion

3. Traverse 4. Exit

Enter your choice:1

Enter the element to insert:30

1. Insertion 2. Deletion

3. Traverse 4. Exit

Enter your choice:1

Enter the element to insert:25

1. Insertion 2. Deletion

3. Traverse 4. Exit

Enter your choice:1

Enter the element to insert:40

1. Insertion 2. Deletion

3. Traverse 4. Exit

Enter your choice:1

Enter the element to insert:35


1. Insertion 2. Deletion

3. Traverse 4. Exit

Enter your choice:1

Enter the element to insert:15

1. Insertion 2. Deletion

3. Traverse 4. Exit

Enter your choice:3

5 10 15 25 30 35 40

1. Insertion 2. Deletion

3. Traverse 4. Exit

Enter your choice:

=== Session Ended. Please Run the code again ===


AVL Tree:

Adelson-Velskii and Landis tree (AVL tree) is the kind of binary


search tree in which the absolute difference between heights of the left subtree
and right subtree must be 0 or 1 or -1

Balanced Factor:

The balanced factor is the difference between the height of


the left and right subtree.

Properties:

The AVL tree has the following properties:

The balanced factor of each node should be 0 or -1, or 1.


Self-balancing binary search tree.
Re-balancing occurs when the absolute difference between the height of
any node's left and right subtree is greater than 1.
The tree in figure (a) is an AVL tree. As you can see, for every node, the height
difference between its left subtree and right subtree does not exceed mod (1).

In figure (b), if you check the node with value 3, its left subtree has
height=2 while the right subtree’s height=0. So, the difference is mod (2-0) =
2. Hence, the AVL property is not satisfied, and it is not an AVL tree.

Balance Factor in AVL Trees:

AVL trees use the balance factor to get a height-balanced tree.

BALANCE FACTOR = height (left subtree) – height (right subtree)


Operations in AVL tree:

AVL tree performs two major operations namely Insert and Delete.

Insertion:

AVL tree insertion pursues the exact procedure as that of binary


search insertion. Rotations can help balance the tree and prevent violation of
the AVL tree property. We first put a node into the proper position in the binary
search tree for insertion in AVL trees.

After satisfying insertion, we calculate each node's Balance Factor


(BF) and review whether it equals -1,0 and 1. If it is not identical, we perform
"rotations" on the tree to balance it.

Deletion:

Deletion in the AVL Trees takes place in three different cases:

1. Deletion from a leaf node:

If the node to be deleted is a leaf node, it is deleted


without any replacement as it does not disturb the binary search tree property.
However, the balance factor may get disturbed, so rotations are applied to
restore it.

2. Deleting a node with one child:

If the node to be removed has a single child,


substitute its value with the value of the child node and later remove the child
node. In case the balance factor gets disrupted, execute rotations as required.
3. Deleting a node with two children:

If the node to be removed has two child


nodes, locate the in-order successor of that node and substitute its value with
the value of the in-order successor. Afterward, attempt to delete the in-order
successor node. If the balance factor surpasses 1 following the deletion, use
balance algorithms.

AVL Rotations:

Different operations which we can perform on an AVL tree are:

1. Search
2. Insertion
3. Deletion
4. Traversal

Left Rotation (LL - Single Rotation):

Left rotation is performed when the


imbalance is created due to the insertion of a new node in the right subtree of a
right subtree or when a subtree becomes right heavy.

Node 6 has a balance factor of -2 after the insertion of node 10. After a single
rotation towards the left, node 8 becomes the root and node 6 becomes its left
child. By doing this, the BST property also remains intact, and the tree becomes
height-balanced.
Right Rotation (RR - Single Rotation):

Right rotation is needed when the


imbalance is created due to the insertion of a node in the left subtree of a left
subtree or when a subtree becomes left heavy.

Node 3 has a balance factor of 2, so it is unbalanced. After a single rotation


towards the right, node 2 becomes the root and node 3 becomes its right
child. And the new root, i.e., node 2, has a balance factor of 0. Hence, the tree
becomes balanced.

Left-Right Rotation (LR - Double Rotation):

It is a double rotation in which a


right rotation follows a left rotation. It is needed when a new node is inserted
in the left subtree of the right subtree of a node.
Node 1 is inserted as the left child of node 2, which is the right child of node
5. See that the balance factor of node 5 becomes 2 after insertion of node 1.
Firstly, we do a left rotation, but the tree is still not balanced. If you see
carefully, the tree is left heavy after this step, so we need a right rotation. After
which node 1, i.e. the newly inserted node, becomes the root.

Right-Left Rotation (RL - Double Rotation):

In this, a right rotation is followed


by a left rotation. It is needed when a node is inserted in the left subtree of the
right subtree of a node.

The insertion of node 6 creates an imbalance. Firstly, we perform a right


rotation which makes node 6 a parent of node 8 and node 8 becomes the right
child of node 6. Next, we perform left rotation on the resulting right-heavy tree
and finally, the tree becomes balanced.
Example:

#include <stdio.h>

#include <stdlib.h>

struct Node

int data;

struct Node *left;

struct Node *right;

int height;

};

int get_Height (struct Node *n)

if(n==NULL)

return 0;

return n->height;

struct Node *create_Node(int data)

struct Node* node = (struct Node *) malloc (sizeof(struct Node));

node->data = data;

node->left = NULL;

node->right = NULL;
node->height = 1;

return node;

int max (int a, int b)

return (a>b)?a:b;

int getBalanceFactor(struct Node * n)

if(n==NULL)

return 0;

return get_Height(n->left) - get_Height(n->right);

struct Node* right_Rotate(struct Node* y)

struct Node* x = y->left;

struct Node* T2 = x->right;

x->right = y;

y->left = T2;

x->height = max(get_Height(x->right), get_Height(x->left)) + 1;


y->height = max(get_Height(y->right), get_Height(y->left)) + 1;

return x;

struct Node* left_Rotate(struct Node* x)

struct Node* y = x->right;

struct Node* T2 = y->left;

y->left = x;

x->right = T2;

x->height = max(get_Height(x->right), get_Height(x->left)) + 1;

y->height = max(get_Height(y->right), get_Height(y->left)) + 1;

return y;

struct Node *insert (struct Node* node, int data)

if (node == NULL)

return create_Node(data);

if (data < node->data)

node->left = insert(node->left, data);

else if (data > node->data)

node->right = insert(node->right, data);

node->height = 1 + max(get_Height(node->left), get_Height(node->right));


int bf = getBalanceFactor(node);

if(bf>1 && data < node->left->data) // Left Left Case

return right_Rotate(node);

if(bf<-1 && data > node->right->data) // Right Right Case

return left_Rotate(node);

if(bf>1 && data > node->left->data) // Left Right Case

node->left = left_Rotate(node->left);

return right_Rotate(node);

if(bf<-1 && data < node->right->data) // Right Left Case

node->right = right_Rotate(node->right);

return left_Rotate(node);

return node;

}
void preOrder(struct Node *root)

if(root != NULL)

printf("%d ", root->data);

preOrder(root->left);

preOrder(root->right);

int main()

struct Node * root = NULL;

root = insert (root, 11);

root = insert (root, 22);

root = insert (root, 24);

root = insert (root, 56);

root = insert (root, 63);

root = insert (root, 35);

printf("%s \n", "The preorder traversal of AVL tree is: ");

preOrder(root);

return 0;

}
Output:

The preorder traversal of AVL tree is:

24 22 11 56 35 63
Constructing an AVL tree

Example: H, I, J, B, A, E, C, F, D, G, K, L

1. Insert H, I, J

Inserting the above elements, especially in the case of H, the


BST becomes unbalanced as the Balance Factor of H is -2. Since the BST is
right-skewed, we will perform RR Rotation on node H.

2. Insert B, A

Inserting the above elements, especially in case of A, the BST


becomes unbalanced as the Balance Factor of H and I is 2, we consider the
first node from the last inserted node i.e., H. Since the BST from H is left-
skewed, we will perform LL Rotation on node H.
3. Insert E:

Inserting E, BST becomes unbalanced as the Balance Factor of I


is 2, since if we travel from E to I we find that it is inserted in the left
subtree of right subtree of I, we will perform LR Rotation on node I. LR
= RR + LL rotation

3 a) We first perform RR rotation on node B


4. Insert C, F, D

inserting C, F, D, BST becomes unbalanced as the Balance


Factor of B and H is -2, since if we travel from D to B we find that it is inserted
in the right subtree of left subtree of B, we will perform RL Rotation on node I.
RL = LL + RR rotation.

4a) We first perform LL rotation on node E


5. Insert G

inserting G, BST become unbalanced as the Balance Factor of H is 2,


since if we travel from G to H, we find that it is inserted in the left subtree of
right subtree of H, we will perform LR Rotation on node I. LR = RR + LL
rotation.

5 a) We first perform RR rotation on node C

5 b) We then perform LL rotation on node H


The resultant balanced tree after LL rotation is:
6. Insert K

inserting K, BST becomes unbalanced as the Balance Factor of I is -


2. Since the BST is right-skewed from I to K, hence we will perform RR
Rotation on the node I.

The resultant balanced tree after RR rotation is:


7. Insert L

Inserting the L tree is still balanced as the Balance Factor of each


node is now either, -1, 0, +1. Hence the tree is a Balanced AVL tree
Advantages of AVL Trees:

The AVL tree is always height-balanced, and its height is always O (log
N), where N is the total number of nodes in the tree.
The time complexities of all the operations are better than BSTs as the
AVL tree has the worst-case time complexity of all operations as O(log
N), while in BST, it is O(N).
AVL trees have self-balancing properties.
AVL trees are not skewed.
AVL trees perform better searching operations than Red-Black Trees
It shows better search time complexity.

Disadvantages of AVL Trees:

Some of the main disadvantages of AVL trees are:

AVL trees are challenging to implement.


For specific operations, AVL trees show relatively high constant factors.
Insertion and deletion are slow in AVL trees.
If you're working on a system with frequent updates, avoid AVL trees.
The AVL Tree applies rotations and the balancing factor, which causes it
to have a complicated data structure.
Difference Between Red-Black and AVL Tree:

Red Black Tree AVL Tree

Searching is comparatively slow. Searching is faster.

Less balanced than the AVL Tree. More balanced than the Red-Black
Tree.

Because of fewer rotations, insertions Because of a greater number of


and deletions are faster. rotations, insertions and deletions
are slower.

Only requires keeping track of colors Each node requires to keep track
assigned to a node. of balanced factors.

Used in the implementation of the set, Used in databases.


map, etc.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy