-
Notifications
You must be signed in to change notification settings - Fork 223
/
Copy pathself-balancing-tree.c
109 lines (90 loc) · 2.4 KB
/
self-balancing-tree.c
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/* Node is defined as :
typedef struct node
{
int val;
struct node* left;
struct node* right;
int ht;
} node; */
int max(int a, int b) {
return (a > b) ? a : b;
}
int get_height(node *root) {
if (!root)
return -1;
else
return root->ht;
}
int set_height(node *root) {
if (!root)
return -1;
else
return 1 + max(get_height(root->left), get_height(root->right));
}
int get_balance_factor(node *root) {
return get_height(root->left) - get_height(root->right);
}
void print_tree(node *root) {
if (!root)
return;
else {
print_tree(root->left);
printf("val = %d ht = %d bf = %d\n", root->val, root->ht, get_balance_factor(root));
print_tree(root->right);
}
}
node *rotate_right(node *root) {
node *new_root = root->left;
root->left = new_root->right;
new_root->right = root;
root->ht = set_height(root);
new_root->ht = set_height(new_root);
return new_root;
}
node *rotate_left(node *root) {
node *new_root = root->right;
root->right = new_root->left;
new_root->left = root;
root->ht = set_height(root);
new_root->ht = set_height(new_root);
return new_root;
}
node *new_node(int val) {
node *nd = (struct node *) calloc(1, sizeof(struct node));
nd->val = val;
nd->left = NULL;
nd->right = NULL;
nd->ht = set_height(nd);
return nd;
}
node *insert(node *root, int value) {
if (!root)
return new_node(value);
// search for place to add new element
if (value > root->val)
root->right = insert(root->right, value);
else
root->left = insert(root->left, value);
int bf = get_balance_factor(root);
//printf("root = %d ht = %d BF = %d\n", root->val, root->ht, bf);
if (bf > 1) {
if (get_height(root->left->left) >= get_height(root->left->right)) {
root = rotate_right(root);
} else {
root->left = rotate_left(root->left);
root = rotate_right(root);
}
} else if (bf < -1) {
if (get_height(root->right->right) >= get_height(root->right->left)) {
root = rotate_left(root);
} else {
root->right = rotate_right(root->right);
root = rotate_left(root);
}
} else {
root->ht = set_height(root);
}
//print_tree(root);
//printf("\n");
return root;
}