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