Download as pdf or txt
Download as pdf or txt
You are on page 1of 6

CSC-112

Data Structures and Algorithms

Lab Report # 11

Name: Muhammad Souban Javaid


Roll No: FA20-BEE-146
Section: 6C
Submitted to: Sir Muhammad Imran
Dated: 23-05-2023
Lab 11: AVL Trees
Implementation

Learning Outcomes:
After successfully completing this lab, the students will be able to:

1. Understand the properties of AVL Trees and their balancing features.


2. Develop C programs for implementing AVL Trees and their balancing features.

In-Lab Tasks:
You are provided with skeleton code that builds a Binary Search Tree by adding 10 nodes to
it. Functions for node insertion and printing the tree (in-order traversal only) are already
implemented. Your task is to modify the insert function to incorporate AVL insertion. You
will find Programming Example on Page 324 of the above-mentioned book useful.

1. Implement the functions rotateLeft() and rotateRight().


Code:
// Function to rotate a node to the right
struct node *rotateRight(struct node *ptr) {
struct node *new_root = ptr->left;
struct node *temp = new_root->right;

new_root->right = ptr;
ptr->left = temp;

// Update the heights of the rotated nodes


ptr->height = 1 + max(height(ptr->left), height(ptr->right));
new_root->height = 1 + max(height(new_root->left), height(new_root-
>right));

return new_root;
}
// Function to rotate a node to the left
struct node *rotateLeft(struct node *ptr) {
struct node *new_root = ptr->right;
struct node *temp = new_root->left;

new_root->left = ptr;
ptr->right = temp;

// Update the heights of the rotated nodes


ptr->height = 1 + max(height(ptr->left), height(ptr->right));
new_root->height = 1 + max(height(new_root->left), height(new_root-
>right));

return new_root;
}

2. Implement the 4 cases of balancing the tree.

void Left(struct node** ptr)


{
struct node* leftNode = (*ptr)->left;

if (leftNode->right != NULL && leftNode->right->height > leftNode-


>left->height)
{
Left(&(leftNode->right));
}

Right(ptr);
}

void Right(struct node** ptr)


{
struct node* rightNode = (*ptr)->right;

(*ptr)->right = rightNode->left;
rightNode->left = *ptr;
*ptr = rightNode;
}
struct node* make_new_node(int insert_data)
{
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->data = insert_data;
temp->left = NULL;
temp->right = NULL;
temp->height = 0;
return temp;
}

void insert_node(struct node **ptr, int insert_data) {


if (*ptr == NULL) {
*ptr = make_new_node(insert_data);
printf("\n%d as Root node inserted!", insert_data);
return;
}

if (insert_data < (*ptr)->data) {


insert_node(&(*ptr)->left, insert_data);
} else if (insert_data > (*ptr)->data) {
insert_node(&(*ptr)->right, insert_data);
} else {
printf("\nNode with data %d already exists in the tree.",
insert_data);
return;
}

// Update the height of the current node


(*ptr)->height = 1 + max(height((*ptr)->left), height((*ptr)->right));

// Check the balance factor of the current node


int balance = get_balance(*ptr);

// Perform necessary rotations to rebalance the tree


if (balance > 1 && insert_data < (*ptr)->left->data) {
*ptr = rotateRight(*ptr);
} else if (balance < -1 && insert_data > (*ptr)->right->data) {
*ptr = rotateLeft(*ptr);
} else if (balance > 1 && insert_data > (*ptr)->left->data) {
(*ptr)->left = rotateLeft((*ptr)->left);
*ptr = rotateRight(*ptr);
} else if (balance < -1 && insert_data < (*ptr)->right->data) {
(*ptr)->right = rotateRight((*ptr)->right);
*ptr = rotateLeft(*ptr);
}
}

// Helper function to get the height of a node


int height(struct node *ptr) {
if (ptr == NULL) {
return -1;
}
return ptr->height;
}

// Helper function to calculate the balance factor of a node


int get_balance(struct node *ptr) {
if (ptr == NULL) {
return 0;
}
return height(ptr->left) - height(ptr->right);
}

// Helper function to find the maximum of two integers


int max(int a, int b) {
return (a > b) ? a : b;
}

Post-Lab Tasks:
Complete the following functions for the BST:
1. Add the delete node functionality.
Code:
bool delete_node(struct node* root, int data)
{
if (root == NULL)
return false;

if (root->data == data)
{
struct node* temp = root;
bool result = delete_child(root, &temp);

free(temp);
return result;
}
else if (data < root->data)
{
if (delete_node(root->left, data))
return true;
}
else
{
if (delete_node(root->right, data))
return true;
}

return false;
}

bool delete_child(struct node* parent, struct node** childPtr)


{
struct node* child = *childPtr;

if (child->left == NULL && child->right == NULL)


{
if (parent->left == child)
parent->left = NULL;
else
parent->right = NULL;

return true;
}
else if (child->left == NULL && child->right != NULL)
{
if (parent->left == child)
parent->left = child->right;
else
parent->right = child->right;

return true;
}
else if (child->left != NULL && child->right == NULL)
{
if (parent->left == child)
parent->left = child->left;
else
parent->right = child->left;

return true;
}
else
{
struct node* predecessor = child->left;
struct node* predecessorParent = child;

while (predecessor->right != NULL)


{
predecessorParent = predecessor;
predecessor = predecessor->right;
}
child->data = predecessor->data;

return delete_child(predecessorParent, &predecessor);


}
}

Conclusion: In conclusion, the AVL Tree implementation lab allowed us to explore the
concept of balanced binary search trees and their significance in maintaining efficient
operations. Through hands-on implementation and problem-solving, we deepened our
understanding of AVL Trees and the challenges involved in ensuring balance. This lab
provided valuable insights into data structure design and sharpened our problem-solving
skills.

------------------------------------------------------------------------------------

You might also like