0% found this document useful (0 votes)
22 views6 pages

FA20 BEE 146 Lab11

The document describes a lab report on implementing AVL trees. It includes learning outcomes, in-lab tasks of implementing rotation functions and balancing cases, and post-lab tasks of adding deletion functionality. Key steps are to rotate nodes, balance the tree on insertion by handling four cases, and implement node deletion.

Uploaded by

Muhammad Ahmad
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)
22 views6 pages

FA20 BEE 146 Lab11

The document describes a lab report on implementing AVL trees. It includes learning outcomes, in-lab tasks of implementing rotation functions and balancing cases, and post-lab tasks of adding deletion functionality. Key steps are to rotate nodes, balance the tree on insertion by handling four cases, and implement node deletion.

Uploaded by

Muhammad Ahmad
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/ 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