AVL strom v C
Jednoduché zadání ze školy, AVL-strom s vkládáním a automatickým vyvažováním.
#include <stdio.h> #include <stdlib.h> #include <math.h> #define MAX(x,y) (x < y ? y : x) #define MIN(x,y) (x > y ? x : y) /** * Tree node */ typedef struct node { int val; char balance; // Vyváženost +1 zatížený doprava, -1 zatížený doleva struct node* left; struct node* right; } s_node; s_node* addNode(int val); s_node* insert(s_node* node, int val); void printTree(s_node* node); void balanceTree(s_node* node); void rotateRight(s_node* node); void rotateLeft(s_node* node); /* * Hlavní část */ s_node* root; int input; int main (void) { do { scanf("%d", &input); root = insert(root, input); } while (input != 0); printTree(root); // kontrola výsledku return 0; } /** * Vytvoří novou node */ s_node* addNode(int val) { s_node* node = malloc(sizeof(s_node)); node->val = val; node->left = NULL; node->right = NULL; node->balance = 0; // Nová node je vždy vybalancovaná return(node); } /** * Vloží novou node do stromu podle hodnoty * Vrátí pointer na root */ s_node* insert(s_node* node, int val) { // Strom je prázdný, vrátit nový if (node == NULL) { return(addNode(val)); } else { // Jinak se rekurentnì dostat dolu do stromu a vložit tam hodnotu if (val < node->val) { node->left = insert(node->left, val); node->balance--; if (node->balance < -1) { // Jsme moc přetížení doleva, spravit! balanceTree(node); } } else if (val > node->val) { node->right = insert(node->right, val); node->balance++; if (node->balance > 1) { // Jsme moc přetizení doprava, spravit! balanceTree(node); } } return(node); // Vrátit vrchní pointer } } /** * Vytiskne strom zleva doprava */ void printTree(s_node* node) { if (node == NULL) { return; } printTree(node->left); printf("%d(%d) ", node->val, node->balance); printTree(node->right); } /** * Vyváží nevyváženou node */ void balanceTree(s_node* node) { // Práva rotace if (node->balance > 0) { if (node->right->balance < 0) { // Práva dvojrotace rotateRight(node->right); } // Práva jednorotace bude v každém případě rotateLeft(node); } else { // Práva rotace if (node->left->balance > 0) { // Práva dvojrotace rotateLeft(node->left); } // Levá jednorotace bude v každém případě rotateRight(node); } } void rotateRight(s_node* node) { s_node* aux, * aux2; aux = node; aux2 = node->left; aux->left = aux2->right; aux2->right = aux; node = aux2; aux->balance += 1 - MIN(0, aux2->balance); aux2->balance += 1 + MAX(0, aux->balance); } void rotateLeft(s_node* node) { s_node* aux, * aux2; aux = node; aux2 = node->right; aux->right = aux2->left; aux2->left = aux; node = aux2; aux->balance += 1 - MIN(0, aux2->balance); aux2->balance += 1 + MAX(0, aux->balance); }