Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
2188 views
1
/*
2
* Main developer: Nico Van Cleemput
3
* In collaboration with: Craig Larson
4
*
5
* Copyright (C) 2013 Ghent University.
6
* Licensed under the GNU GPL, read the file LICENSE.txt for details.
7
*/
8
9
#include <stdlib.h>
10
#include <string.h>
11
#include "bintrees.h"
12
#include "util.h"
13
14
//------ Node operations -------
15
16
void addChildToNode(NODE *parent, NODE *child){
17
if(parent->left == NULL){
18
parent->left = child;
19
parent->type = 1;
20
child->depth = parent->depth + 1;
21
} else if(parent->right == NULL){
22
parent->right = child;
23
parent->type = 2;
24
child->depth = parent->depth + 1;
25
} else {
26
BAILOUT("Parent already has two children")
27
}
28
}
29
30
NODE *removeChildFromNode(NODE *parent){
31
if(parent->right != NULL){
32
NODE *child = parent->right;
33
parent->right = NULL;
34
parent->type = 1;
35
return child;
36
} else if(parent->left != NULL){
37
NODE *child = parent->left;
38
parent->left = NULL;
39
parent->type = 0;
40
return child;
41
} else {
42
BAILOUT("Parent has no children")
43
}
44
}
45
46
void getOrderedNodes(NODE *node, NODE **orderedNodes, int *currentPosition){
47
if(node->type==2){
48
getOrderedNodes(node->left, orderedNodes, currentPosition);
49
getOrderedNodes(node->right, orderedNodes, currentPosition);
50
orderedNodes[*currentPosition] = node;
51
node->pos = *currentPosition;
52
(*currentPosition)++;
53
} else if(node->type==1){
54
getOrderedNodes(node->left, orderedNodes, currentPosition);
55
orderedNodes[*currentPosition] = node;
56
node->pos = *currentPosition;
57
(*currentPosition)++;
58
} else {
59
orderedNodes[*currentPosition] = node;
60
node->pos = *currentPosition;
61
(*currentPosition)++;
62
}
63
}
64
65
//------ Tree operations -------
66
67
void initTree(TREE *tree){
68
int i;
69
for(i=0; i<MAX_NODES_USED - 1; i++){
70
tree->unusedStack[i] = malloc(sizeof(NODE));
71
tree->unusedStack[i]->left = tree->unusedStack[i]->right = NULL;
72
tree->unusedStack[i]->depth = 0;
73
tree->unusedStack[i]->type = 0;
74
}
75
tree->unusedStackSize = MAX_NODES_USED - 1;
76
77
for(i=0; i<MAX_TREE_DEPTH+1; i++){
78
tree->levelWidth[i]=0;
79
}
80
81
tree->binaryCount = tree->unaryCount = 0;
82
tree->depth = 0;
83
84
//create the root
85
NODE *root = malloc(sizeof(NODE));
86
root->left = root->right = NULL;
87
root->depth = 0;
88
root->type = 0;
89
90
//set the root
91
tree->root = root;
92
tree->levelWidth[0] = 1;
93
tree->nodesAtDepth[0][0] = tree->root;
94
}
95
96
void copyNode_(NODE *original, NODE *copy, TREE *copyTree){
97
//copy fields
98
copy->depth = original->depth;
99
copy->pos = original->pos;
100
copy->type = original->type;
101
copy->contentLabel[0] = original->contentLabel[0];
102
copy->contentLabel[1] = original->contentLabel[1];
103
104
//copy children
105
if(original->left == NULL){
106
copy->left = NULL;
107
} else {
108
(copyTree->unusedStackSize)--;
109
copy->left = copyTree->unusedStack[copyTree->unusedStackSize];
110
copyNode_(original->left, copy->left, copyTree);
111
}
112
if(original->right == NULL){
113
copy->right = NULL;
114
} else {
115
(copyTree->unusedStackSize)--;
116
copy->right = copyTree->unusedStack[copyTree->unusedStackSize];
117
copyNode_(original->right, copy->right, copyTree);
118
}
119
120
}
121
122
void copyTree(TREE *tree, TREE *copy){
123
//copy fields
124
copy->depth = tree->depth;
125
copy->unaryCount = tree->unaryCount;
126
copy->binaryCount = tree->binaryCount;
127
memcpy(copy->levelWidth, tree->levelWidth, sizeof(int)*(MAX_TREE_DEPTH+1));
128
129
//copy structures
130
copy->unusedStackSize = MAX_NODES_USED - 1;
131
copyNode_(tree->root, copy->root, copy);
132
133
//check that unusedStack size is the same
134
if(tree->unusedStackSize != copy->unusedStackSize){
135
BAILOUT("Error while copying tree")
136
}
137
}
138
139
void freeTree(TREE *tree){
140
int i;
141
for(i=0; i<MAX_NODES_USED - 1; i++){
142
free(tree->unusedStack[i]);
143
}
144
free(tree->root);
145
}
146
147
void addChildToNodeInTree(TREE *tree, NODE *parent){
148
NODE *child = tree->unusedStack[--(tree->unusedStackSize)];
149
addChildToNode(parent, child);
150
if(child->depth > tree->depth) tree->depth = child->depth;
151
152
if(parent->type==2){
153
tree->unaryCount--;
154
tree->binaryCount++;
155
} else {
156
tree->unaryCount++;
157
}
158
159
tree->nodesAtDepth[child->depth][(tree->levelWidth[child->depth])++] = child;
160
}
161
162
void removeChildFromNodeInTree(TREE *tree, NODE *parent){
163
NODE *child = removeChildFromNode(parent);
164
tree->unusedStack[tree->unusedStackSize] = child;
165
(tree->unusedStackSize)++;
166
tree->levelWidth[child->depth]--;
167
168
if(tree->levelWidth[child->depth]==0){
169
tree->depth--;
170
}
171
172
if(parent->type==1){
173
tree->binaryCount--;
174
tree->unaryCount++;
175
} else {
176
tree->unaryCount--;
177
}
178
}
179
180