-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbstree.h
198 lines (155 loc) · 4.1 KB
/
bstree.h
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/* Binary Search Tree implementation */
typedef struct bstree_node bstree_node;
struct bstree_node {
int key;
void *val;
struct bstree_node *left;
struct bstree_node *right;
};
typedef struct {
bstree_node *root;
int size;
} bstree;
void bstree_put(bstree *tree, int key, void *val);
void* bstree_get(bstree *tree, int key);
void bstree_del(bstree *tree, int key);
int bstree_size(bstree *tree);
int* bstree_keys(bstree *tree);
void bstree_destroy(bstree *tree);
bstree_node* _bstree_new_node(int key, void *val);
int _bstree_put(bstree_node **node_ptr, int key, void *val);
void* _bstree_get(bstree_node *node, int key);
int _bstree_del(bstree *tree, bstree_node *parent, bstree_node *node, int key);
bstree_node* _bstree_most_left_node_parent(bstree_node *parent, bstree_node *node);
void _bstree_keys(bstree_node *node, int *rv, int i);
void _bstree_destroy(bstree_node *node);
// PUBLIC API
bstree* bstree_new() {
bstree *tree = malloc(sizeof(bstree));
tree->size = 0;
tree->root = NULL;
return tree;
}
void bstree_put(bstree *tree, int key, void *val) {
tree->size += _bstree_put(&tree->root, key, val);
}
void* bstree_get(bstree *tree, int key) {
return _bstree_get(tree->root, key);
}
void bstree_del(bstree *tree, int key) {
tree->size -= _bstree_del(tree, NULL, tree->root, key);
}
int bstree_size(bstree *tree) {
return tree->size;
}
int* bstree_keys(bstree *tree) {
int *rv = malloc(bstree_size(tree) * sizeof(int));
_bstree_keys(tree->root, rv, 0);
return rv;
}
void bstree_destroy(bstree *tree) {
_bstree_destroy(tree->root);
free(tree);
}
// PRIVATE API
bstree_node* _bstree_new_node(int key, void *val) {
bstree_node *node = malloc(sizeof(bstree_node));
node->left = node->right = NULL;
node->key = key;
node->val = val;
return node;
}
int _bstree_put(bstree_node **node_ptr, int key, void *val) {
bstree_node *node = *node_ptr;
if (node == NULL) {
*node_ptr = _bstree_new_node(key, val);
return 1;
}
if (key > node->key)
return _bstree_put(&node->right, key, val);
if (key < node->key)
return _bstree_put(&node->left, key, val);
node->key = key;
node->val = val;
return 0;
}
void* _bstree_get(bstree_node *node, int key) {
if (node == NULL)
return NULL;
if (key > node->key)
return _bstree_get(node->right, key);
if (key < node->key)
return _bstree_get(node->left, key);
return node->val;
}
int _bstree_del(bstree *tree, bstree_node *parent, bstree_node *node, int key) {
if (node == NULL)
return 0;
if (key > node->key)
return _bstree_del(tree, node, node->right, key);
if (key < node->key)
return _bstree_del(tree, node, node->left, key);
if (node->left == NULL && node->right == NULL) {
if (parent == NULL) {
tree->root = NULL;
}
else if (parent->left == node) {
parent->left = NULL;
}
else {
parent->right = NULL;
}
goto RET;
}
if (node->left == NULL) {
if (parent == NULL) {
tree->root = node->right;
}
else if (parent->left == node) {
parent->left = node->right;
}
else {
parent->right = node->right;
}
goto RET;
}
if (node->right == NULL) {
if (parent == NULL) {
tree->root = node->left;
}
else if (parent->left == node) {
parent->left = node->left;
}
else {
parent->right = node->left;
}
goto RET;
}
bstree_node *next_node_parent = _bstree_most_left_node_parent(NULL, node->right);
bstree_node *next_node = next_node_parent == NULL ? node->right : next_node_parent->left;
node->key = next_node->key;
node->val = next_node->val;
return _bstree_del(tree, next_node_parent ? next_node_parent : node, next_node, next_node->key);
RET:
free(node);
return 1;
}
bstree_node* _bstree_most_left_node_parent(bstree_node *parent, bstree_node *node) {
if (node->left == NULL)
return parent;
return _bstree_most_left_node_parent(node, node->left);
}
void _bstree_keys(bstree_node *node, int *rv, int i) {
if (node == NULL)
return;
rv[i++] = node->key;
_bstree_keys(node->left, rv, i);
_bstree_keys(node->right, rv, i);
}
void _bstree_destroy(bstree_node *node) {
if (node == NULL)
return;
_bstree_destroy(node->left);
_bstree_destroy(node->right);
free(node);
}