Skip to content

Commit

Permalink
Tree
Browse files Browse the repository at this point in the history
  • Loading branch information
Salini-sat committed Oct 4, 2024
1 parent 3464663 commit a571bfc
Show file tree
Hide file tree
Showing 6 changed files with 790 additions and 0 deletions.
215 changes: 215 additions & 0 deletions AVL Tree/program.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
#include <stdio.h>
#include <stdlib.h>

// AVL Tree
struct Node {
int data;
struct Node* left;
struct Node* right;
int height;
};


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


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


struct Node* createNode(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;
}


struct Node* rightRotate(struct Node* y) {
struct Node* x = y->left;
struct Node* T2 = x->right;

x->right = y;
y->left = T2;

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

return x;
}

struct Node* leftRotate(struct Node* x) {
struct Node* y = x->right;
struct Node* T2 = y->left;


y->left = x;
x->right = T2;


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

return y;
}

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

struct Node* insertNode(struct Node* node, int data) {

if (node == NULL)
return createNode(data);

if (data < node->data)
node->left = insertNode(node->left, data);
else if (data > node->data)
node->right = insertNode(node->right, data);
else
return node;


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

int balance = getBalance(node);


if (balance > 1 && data < node->left->data)
return rightRotate(node);

if (balance < -1 && data > node->right->data)
return leftRotate(node);

if (balance > 1 && data > node->left->data) {
node->left = leftRotate(node->left);
return rightRotate(node);
}

if (balance < -1 && data < node->right->data) {
node->right = rightRotate(node->right);
return leftRotate(node);
}

return node;
}

struct Node* findMin(struct Node* node) {
struct Node* current = node;
while (current->left != NULL)
current = current->left;
return current;
}

struct Node* deleteNode(struct Node* root, int data) {

if (root == NULL)
return root;

if (data < root->data)
root->left = deleteNode(root->left, data);
else if (data > root->data)
root->right = deleteNode(root->right, data);
else {

if (root->left == NULL || root->right == NULL) {
struct Node* temp = root->left ? root->left : root->right;
if (temp == NULL) {
temp = root;
root = NULL;
} else
*root = *temp;
free(temp);
} else {

struct Node* temp = findMin(root->right);
root->data = temp->data;
root->right = deleteNode(root->right, temp->data);
}
}

if (root == NULL)
return root;

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


int balance = getBalance(root);


if (balance > 1 && getBalance(root->left) >= 0)
return rightRotate(root);

if (balance > 1 && getBalance(root->left) < 0) {
root->left = leftRotate(root->left);
return rightRotate(root);
}

if (balance < -1 && getBalance(root->right) <= 0)
return leftRotate(root);

if (balance < -1 && getBalance(root->right) > 0) {
root->right = rightRotate(root->right);
return leftRotate(root);
}

return root;
}

int searchNode(struct Node* root, int data) {
if (root == NULL)
return 0;
if (data == root->data)
return 1;
else if (data < root->data)
return searchNode(root->left, data);
else
return searchNode(root->right, data);
}

void inorderTraversal(struct Node* root) {
if (root != NULL) {
inorderTraversal(root->left);
printf("%d -> ", root->data);
inorderTraversal(root->right);
}
}

int main() {
struct Node* root = NULL;

root = insertNode(root, 10);
root = insertNode(root, 20);
root = insertNode(root, 30);
root = insertNode(root, 40);
root = insertNode(root, 50);
root = insertNode(root, 25);

printf("In-order traversal after insertions:\n");
inorderTraversal(root);
printf("NULL\n");

// Deletion
root = deleteNode(root, 20);
printf("In-order traversal after deleting 20:\n");
inorderTraversal(root);
printf("NULL\n");

// Searching
int searchKey = 25;
if (searchNode(root, searchKey))
printf("Node %d found in the AVL tree.\n", searchKey);
else
printf("Node %d not found in the AVL tree.\n", searchKey);

return 0;
}
92 changes: 92 additions & 0 deletions AVL Tree/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# AVL Tree

## Description

An AVL Tree is a self-balancing binary search tree (BST) where the height difference (balance factor) between the left and right subtrees of any node is at most 1. This ensures that the tree remains balanced, providing better performance for insertion, deletion, and search operations compared to an unbalanced binary tree.

### Problem Definition

The goal is to implement a self-balancing binary search tree (AVL tree) to efficiently support:

1. Insertion of elements while keeping the tree balanced.


2. Deletion of elements, ensuring the balance of the tree is restored if necessary.


3. Searching for elements efficiently.


4. Tree traversals to visit nodes in specific orders (in-order, pre-order, post-order).

AVL Property:

After every insertion or deletion, the balance factor (difference between the heights of the left and right subtrees) of each node must be maintained between -1 and 1.

### Algorithm Review

1. Insertion

Insert the node like in a regular binary search tree (BST).

After insertion, check the balance factor of every ancestor node.

If the tree becomes unbalanced, perform one of the following rotations:

Left Rotation

Right Rotation

Left-Right Rotation

Right-Left Rotation



2. Deletion

Delete the node like in a regular BST.

After deletion, check the balance factor of affected nodes.

If unbalanced, perform the necessary rotation(s) to restore balance.


3. Searching

Same as searching in a binary search tree: move left if the value is smaller, and move right if the value is larger.


4. Tree Traversals

In-order traversal (LNR): Returns elements in sorted order.

Pre-order traversal (NLR): Visits root first, followed by left and right subtrees.

Post-order traversal (LRN): Visits children first, followed by root.


5. Rotations

Single Rotations (Left or Right) are used when the tree is unbalanced on one side.

Double Rotations (Left-Right or Right-Left) are used when the tree is unbalanced in both directions.

Time Complexity

In an AVL tree, the height is always maintained as O(log n), ensuring efficient operations:

Insertion: O(log n)

Insertion may involve O(log n) rotations to rebalance the tree.


Deletion: O(log n)

Deletion may require O(log n) rotations to restore balance.

Search: O(log n)

The tree remains balanced, so the search operation takes logarithmic time.

Traversal: O(n)
Loading

0 comments on commit a571bfc

Please sign in to comment.