college/Spring-2024/CS-2124/Assignment-4/src/avl_tree.c

182 lines
4.6 KiB
C

// ==== Intructions ====
// • Write a program that will have pre defined input as numbers (1,2,3,4,5)
// • Then program will first create a BST of the input and print that out
// • Then the program will balance the BST and print out the AVL tree
// (pre-order)
//
// Steps
// • Create BST (0.5-point)
// • Balance the tree (i.e. AVL tree) (0.5-point)
// Output:
// • Print BST Pre-order (1-point)
// • Print Balanced-AVL Pre-order (1-point)
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
int max(int a, int b) {
int max = (a > b) ? a : b;
return max;
}
typedef struct BstNode {
int value;
int height;
int balance;
struct BstNode *left;
struct BstNode *right;
} BstNode;
BstNode *bst_new(int value) {
BstNode *bst = (BstNode *)malloc(sizeof(BstNode));
bst->value = value;
bst->height = 0;
bst->balance = 0;
bst->left = NULL;
bst->right = NULL;
return bst;
}
void bst_print_preorder(BstNode *node) {
if (node == NULL) {
return;
}
printf("%d, ", node->value);
bst_print_preorder(node->left);
bst_print_preorder(node->right);
}
void bst_dbg(BstNode *node) {
bst_print_preorder(node);
printf("BstNode {\n value: %d,\n height: %d,\n balance: %d\n}\n",
node->value, node->height, node->balance);
}
BstNode *bst_search(BstNode *node, int value) {
if (node == NULL) {
return NULL;
}
if (node->value == value) {
return node;
}
if (value < node->value) {
return bst_search(node->left, value);
} else {
return bst_search(node->right, value);
}
}
bool bst_contains(BstNode *node, int value) {
return (bst_search(node, value) != NULL);
}
int bst_height(BstNode *node) {
if (node == NULL) {
return -1;
}
int left_height = bst_height(node->left);
int right_height = bst_height(node->right);
return max(left_height, right_height) + 1;
}
void bst_update(BstNode *node) {
int left_height = bst_height(node->left);
int right_height = bst_height(node->right);
node->height = max(left_height, right_height) + 1;
node->balance = left_height - right_height;
}
BstNode *avl_right_rotate(BstNode *node) {
BstNode *left_child = node->left;
node->left = left_child->right;
left_child->right = node;
bst_update(node);
bst_update(left_child);
return node;
}
BstNode *avl_left_rotate(BstNode *node) {
BstNode *right_child = node->right;
node->right = right_child->left;
right_child->left = node;
bst_update(node);
bst_update(right_child);
return right_child;
}
/**
* @brief Balances a single node according to the AVL algorithm
*
* @param node The node to balance
* @return The balanced node
*/
BstNode *avl_balance_node(BstNode *node) {
if (node->balance == 2) {
if (node->left->balance >= 0) {
node = avl_right_rotate(node);
} else {
node = avl_left_rotate(node->left);
node = avl_right_rotate(node);
}
} else if (node->balance == -2) {
if (node->right->balance <= 0) {
node = avl_left_rotate(node);
} else {
node = avl_right_rotate(node->right);
node = avl_left_rotate(node);
}
}
return node;
}
/**
* @brief Insert a value into a Binary Search Tree in place
*
* @param node The given binary search tree to insert into
* @param value The value to insert
* @param balance Whether to balance the insertion with AVL
*/
void bst_insert(BstNode **node, int value, bool balance) {
if (*node == NULL)
*node = bst_new(value);
else if ((*node)->value == value)
// No duplicates allowed in our implementation
return;
else if ((*node)->value > value)
bst_insert(&(*node)->left, value, balance);
else
bst_insert(&(*node)->right, value, balance);
bst_update(*node);
if (balance)
*node = avl_balance_node(*node);
}
int main(int argc, char *argv[]) {
printf("Price Hiller, zfp106 (Spring 2024)\n");
printf("==================================\n");
printf("Unbalanced BST Pre-Order: ");
BstNode *bst = bst_new(1);
int input[] = {2, 3, 4, 5};
for (int i = 0; i < sizeof(input)/sizeof(input[0]); i++) {
bst_insert(&bst, input[i], false);
}
bst_print_preorder(bst);
printf("\nBalanced AVL Tree Pre-Order: ");
BstNode *avl = bst_new(1);
for (int i = 0; i < sizeof(input)/sizeof(input[0]); i++) {
bst_insert(&avl, input[i], true);
}
bst_print_preorder(avl);
printf("\n");
return EXIT_SUCCESS;
}