From 3e872f0cb712f49288ac4296e1b7bd75b9b985f7 Mon Sep 17 00:00:00 2001 From: Bruno Freitas Tissei <bft15@inf.ufpr.br> Date: Fri, 18 May 2018 13:05:14 +0200 Subject: [PATCH] Add avl Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br> --- structure/avl.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 structure/avl.cpp diff --git a/structure/avl.cpp b/structure/avl.cpp new file mode 100644 index 0000000..ee11442 --- /dev/null +++ b/structure/avl.cpp @@ -0,0 +1,109 @@ +/** + * AVL tree + * + * Complexity (Time): O(log n) + * Complexity (Space): O(n) + */ + +typedef struct avl_node_t { + int key; + int size; // number of nodes bellow (optional) + int height; // height of node + + struct avl_node_t *left; + struct avl_node_t *right; +} avl_node_t; + + +typedef struct avl_t { + avl_node_t *root; +} avl_t; + + +static inline int get_height(avl_node_t *node) { + return (node == NULL) ? 0 : node->height; +} + + +static inline int get_size(avl_node_t *node) { + return (node == NULL) ? 0 : node->size; +} + + +static inline int get_balance(avl_node_t *node) { + return (node == NULL) ? 0 : get_height(node->left) - get_height(node->right); +} + + +avl_node_t *rotate_right(avl_node_t *node) { + avl_node_t *aux1 = node->left; + avl_node_t *aux2 = aux1->right; + + aux1->right = node; + node->left = aux2; + + node->height = max(get_height(node->left), get_height(node->right)) + 1; + aux1->height = max(get_height(aux1->left), get_height(aux1->right)) + 1; + + node->size = get_size(node->left) + get_size(node->right) + 1; + aux1->size = get_size(aux1->left) + get_size(aux1->right) + 1; + + return aux1; +} + + +avl_node_t *rotate_left(avl_node_t *node) { + avl_node_t *aux1 = node->right; + avl_node_t *aux2 = aux1->left; + + aux1->left = node; + node->right = aux2; + + node->height = max(get_height(node->left), get_height(node->right)) + 1; + aux1->height = max(get_height(aux1->left), get_height(aux1->right)) + 1; + + node->size = get_size(node->left) + get_size(node->right) + 1; + aux1->size = get_size(aux1->left) + get_size(aux1->right) + 1; + + return aux1; +} + + +// Insert key in AVL +avl_node_t *avl_insert(avl_t *avl, avl_node_t *node, int key) { + if (node == NULL) { + avl_node_t *neu = new avl_node_t; + + neu->key = key; + neu->left = neu->right = NULL; + neu->height = neu->size = 1; + + if (avl->root == NULL) + avl->root = neu; + + return neu; + } + + if (key < node->key) + node->left = avl_insert(avl, node->left, key); + else + node->right = avl_insert(avl, node->right, key); + + int balance = get_balance(node); + node->height = max(get_height(node->left), get_height(node->right)) + 1; + node->size = get_size(node->left) + get_size(node->right) + 1; + + if (balance > 1 && key < node->left->key) { + return rotate_right(node); + } else if (balance < -1 && key > node->right->key) { + return rotate_left(node); + } else if (balance > 1 && key > node->left->key) { + node->left = rotate_left(node->left); + return rotate_right(node); + } else if (balance < -1 && key < node->right->key) { + node->right = rotate_right(node->right); + return rotate_left(node); + } + + return node; +} -- GitLab