summaryrefslogtreecommitdiff
path: root/lib/tree.c
blob: 081f1d105a5229922d5a1ac6ef5270b8251f0285 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

#include "tree.h"

node_t *tree_createNode(v_t value, v_t level, node_t *left, node_t *right) {
  node_t *node = (node_t *)malloc(sizeof(node_t));

  node->value = value;
  node->level = level;
  node->left = left;
  node->right = right;

  return node;
}

void tree_freeNode(node_t *node) {
  if (node != NULL) {
    tree_freeNode(node->left);
    tree_freeNode(node->right);
    free(node);
  }
}

void tree_skew(node_t **T) {
  if (*T != NULL) {
    if ((*T)->left != NULL) {
      if ((*T)->left->level == (*T)->level) {
        node_t *L = (*T)->left;
        (*T)->left = L->right;
        L->right = (*T);

        *T = L;
      }
    }
  }
}

void tree_split(node_t **T) {
  if (*T != NULL) {
    if ((*T)->right != NULL) {
      if ((*T)->right->right != NULL) {
        if ((*T)->level == (*T)->right->right->level) {
          node_t *R = (*T)->right;
          (*T)->right = R->left;
          R->left = *T;
          R->level = R->level + 1;
          *T = R;
        }
      }
    }
  }
}

void tree_insert(node_t **T, v_t x) {
  if (*T == NULL) {
    *T = tree_createNode(x, 1, NULL, NULL);
  } else if (x < (*T)->value) {
    node_t *L = (*T)->left;
    tree_insert(&L, x);
    (*T)->left = L;
  } else if (x > (*T)->value) {
    node_t *R = (*T)->right;
    tree_insert(&R, x);
    (*T)->right = R;
  }

  tree_skew(T);
  tree_split(T);
}

bool tree_contains(node_t *T, v_t x) {
  if (T == NULL) {
    return false;
  } else if (x < T->value) {
    return tree_contains(T->left, x);
  } else if (x > T->value) {
    return tree_contains(T->right, x);
  } else {
    return true;
  }
}