aboutsummaryrefslogtreecommitdiff
path: root/Computer_Science/data_structures/chapter_4/avl_tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'Computer_Science/data_structures/chapter_4/avl_tree.c')
-rw-r--r--Computer_Science/data_structures/chapter_4/avl_tree.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/Computer_Science/data_structures/chapter_4/avl_tree.c b/Computer_Science/data_structures/chapter_4/avl_tree.c
new file mode 100644
index 0000000..da6ab0d
--- /dev/null
+++ b/Computer_Science/data_structures/chapter_4/avl_tree.c
@@ -0,0 +1,164 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "avl_tree.h"
+#include "print_ascii_tree.h"
+
+AvlTree make_empty(AvlTree t)
+{
+ if(t != NULL) {
+ make_empty(t->left);
+ make_empty(t->right);
+ free(t);
+ }
+
+ return NULL;
+}
+
+Position find(elem_t x, AvlTree t)
+{
+ if(t == NULL)
+ return NULL;
+ else if(x == t->elem)
+ return t;
+ else if(x > t->elem)
+ return find(x, t->right);
+ else if(x < t->elem)
+ return find(x, t->left);
+}
+
+Position find_min(AvlTree t)
+{
+ if(t == NULL)
+ return NULL;
+ else if(t->left == NULL)
+ return t;
+ else
+ return find_min(t->left);
+}
+
+Position find_max(AvlTree t)
+{
+ if(t == NULL)
+ return NULL;
+ else if(t->right == NULL)
+ return t;
+ else
+ return find_max(t->right);
+}
+
+static int height(Position p)
+{
+ return p == NULL ? -1 : p->height;
+}
+
+static Position single_rotate_with_left(Position p)
+{
+ Position p_left;
+
+ p_left = p->left;
+ p->left = p_left->right;
+ p_left->right = p;
+
+ /* derectly use ->height may case some problem */
+ p->height = MAX(height(p->left), height(p->right)) + 1;
+ p_left->height = MAX(height(p_left->left), p->height) + 1;
+
+ /* return new Node */
+ return p_left;
+}
+
+static Position single_rotate_with_right(Position p)
+{
+ Position p_right;
+
+ p_right = p->right;
+ p->right = p_right->left;
+ p_right->left = p;
+
+ p->height = MAX(height(p->left), height(p->right)) + 1;
+ p_right->height = MAX(height(p_right->right), p->height) + 1;
+
+ /* return new node */
+ return p_right;
+
+}
+
+static Position double_rotate_with_left(Position p)
+{
+ p->left = single_rotate_with_right(p->left);
+
+ return single_rotate_with_left(p);
+}
+
+
+static Position double_rotate_with_right(Position p)
+{
+
+ p->right = single_rotate_with_left(p->right);
+
+ return single_rotate_with_right(p);
+}
+
+AvlTree insert(elem_t x, AvlTree t)
+{
+ if(t == NULL) {
+ t = malloc(sizeof(struct AvlNode));
+ t->elem = x;
+ t->height = 0;
+ t->left = t->right = NULL;
+ } else if(x > t->elem) {
+ t->right = insert(x, t->right);
+ /* > 1 or == 2? */
+ if(height(t->right) - height(t->left) > 1) {
+ if(x > t->right->elem)
+ t = single_rotate_with_right(t);
+ if(x < t->right->elem)
+ t = double_rotate_with_right(t);
+ }
+ } else if(x < t->elem) {
+ t->left = insert(x, t->left);
+
+ if(height(t->left) - height(t->right) == 2) {
+ if(x < t->left->elem)
+ t = single_rotate_with_left(t);
+ if(x > t->left->elem)
+ t = double_rotate_with_left(t);
+ }
+ }
+
+ /* else do nothing, but update the height */
+ t->height = MAX(height(t->left), height(t->right)) + 1;
+
+ return t;
+}
+
+/* lazy delete ? */
+AvlTree delete(elem_t x, AvlTree t)
+{
+
+}
+
+void test()
+{
+ AvlTree t = NULL;
+
+ t = insert(4, t);
+ t = insert(3, t);
+ t = insert(2, t);
+ t = insert(1, t);
+ t = insert(8, t);
+ t = insert(9, t);
+
+ printf("min:%d\n", find_min(t)->elem);
+ printf("max:%d\n", find_max(t)->elem);
+ printf("find 2:%d\n", find(2, t)->elem);
+ print_ascii_tree(t);
+}
+
+int main()
+{
+ test();
+ return 0;
+}