-
Notifications
You must be signed in to change notification settings - Fork 0
/
btree.c
119 lines (109 loc) · 3.94 KB
/
btree.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
110
111
112
113
114
115
116
117
118
119
//
// Created by Freedom Coder on 19.10.2021.
//
#include <stdlib.h>
#include "btree.h"
void BT_construct(struct BTree *tree, int (*comparator)(TBINode a, TBINode b)) {
tree->root = NULL;
tree->comparator = comparator;
}
void BT_insert(struct BTree *tree, TBINode element) {
struct BTNode **currNode = &tree->root;
struct BTNode *prevNode = NULL;
while (1)
if (*currNode)
if (tree->comparator(element, (*currNode)->data) > 0)
prevNode = *currNode, currNode = &(*currNode)->right;
else
prevNode = *currNode, currNode = &(*currNode)->left;
else {
*currNode = malloc(sizeof(struct BTNode));
(*currNode)->data = element;
(*currNode)->parent = prevNode;
(*currNode)->left = NULL;
(*currNode)->right = NULL;
break;
}
}
int BT_contains_internal(struct BTree *tree, struct BTNode *branch, TBINode element) {
if (!branch) return 0;
if (!tree->comparator(branch->data, element)) return 1;
if (BT_contains_internal(tree, branch->left, element)) return 1;
if (BT_contains_internal(tree, branch->right, element)) return 1;
return 0;
}
int BT_contains(struct BTree *tree, TBINode element) {
return BT_contains_internal(tree, tree->root, element);
}
void BT_remove(struct BTree *tree, TBINode element) {
struct BTNode **currNode = &tree->root;
while (1)
if (*currNode) {
int comp = tree->comparator(element, (*currNode)->data);
if (comp > 0)
currNode = &(*currNode)->right;
else if (comp < 0)
currNode = &(*currNode)->left;
else {
struct BTNode **replacement = &(*currNode)->left;
while ((*replacement)->right) replacement = &(*replacement)->right;
(*replacement)->right = (*currNode)->right;
if (*replacement != (*currNode)->left) (*replacement)->left = (*currNode)->left;
free(*currNode);
*currNode = *replacement;
*replacement = NULL;
break;
}
}
else
break; // not found
}
void BT_consume_internal(struct BTNode *branch, void (*consumer)(TBINode element), int bt_strategy) {
if (!branch) return;
switch (bt_strategy) {
case BT_STRATEGY_INFIXED:
BT_consume_internal(branch->left, consumer, bt_strategy);
consumer(branch->data);
BT_consume_internal(branch->right, consumer, bt_strategy);
break;
case BT_STRATEGY_PREFIXED:
consumer(branch->data);
BT_consume_internal(branch->left, consumer, bt_strategy);
BT_consume_internal(branch->right, consumer, bt_strategy);
break;
case BT_STRATEGY_POSTFIXED:
BT_consume_internal(branch->left, consumer, bt_strategy);
BT_consume_internal(branch->right, consumer, bt_strategy);
consumer(branch->data);
break;
case BT_STRATEGY_INVERSE:
consumer(branch->data);
BT_consume_internal(branch->right, consumer, bt_strategy);
BT_consume_internal(branch->left, consumer, bt_strategy);
break;
}
}
struct BTNode* BT_next(struct BTNode* curr) {
if (curr)
{
// if (curr->left) return curr->left;
if (curr->right) {
curr = curr->right;
while (curr->left) curr = curr->left;
return curr;
}
return curr->parent;
} else return NULL;
}
void BT_consume(struct BTree *tree, void (*consumer)(TBINode element), int bt_strategy) {
BT_consume_internal(tree->root, consumer, bt_strategy);
}
void BT_destruct_internal(struct BTNode *branch) {
if (!branch) return;
BT_destruct_internal(branch->left);
BT_destruct_internal(branch->right);
free(branch);
}
void BT_destruct(struct BTree *tree) {
BT_destruct_internal(tree->root);
}