1
+ /**
2
+ * @file
3
+ * @brief A basic unbalanced binary search tree implementation in C.
4
+ * @details The implementation has the following functionalities implemented:
5
+ * - Insertion
6
+ * - Deletion
7
+ * - Search by key value
8
+ * - Listing of node keys in order of value (from left to right)
9
+ */
1
10
#include <stdio.h>
2
11
#include <stdlib.h>
3
12
4
- /* A basic unbalanced binary search tree implementation in C, with the following
5
- functionalities implemented:
6
- - Insertion
7
- - Deletion
8
- - Search by key value
9
- - Listing of node keys in order of value (from left to right)
10
- */
11
-
12
- // Node, the basic data structure in the tree
13
+ /** Node, the basic data structure in the tree */
13
14
typedef struct node
14
15
{
15
- // left child
16
- struct node * left ;
17
-
18
- // right child
19
- struct node * right ;
20
-
21
- // data of the node
22
- int data ;
16
+ struct node * left ; /**< left child */
17
+ struct node * right ; /**< right child */
18
+ int data ; /**< data of the node */
23
19
} node ;
24
20
25
- // The node constructor, which receives the key value input and returns a node
26
- // pointer
21
+ /** The node constructor, which receives the key value input and returns a node
22
+ * pointer
23
+ * @param data data to store in a new node
24
+ * @returns new node with the provided data
25
+ * @note the node must be deleted before program terminates to avoid memory
26
+ * leaks
27
+ */
27
28
node * newNode (int data )
28
29
{
29
30
// creates a slug
@@ -37,61 +38,82 @@ node *newNode(int data)
37
38
return tmp ;
38
39
}
39
40
40
- // Insertion procedure, which inserts the input key in a new node in the tree
41
+ /** Insertion procedure, which inserts the input key in a new node in the tree
42
+ * @param root pointer to parent node
43
+ * @param data value to store int he new node
44
+ * @returns pointer to parent node
45
+ */
41
46
node * insert (node * root , int data )
42
47
{
43
48
// If the root of the subtree is null, insert key here
44
49
if (root == NULL )
50
+ {
45
51
root = newNode (data );
46
- // If it isn't null and the input key is greater than the root key, insert
47
- // in the right leaf
52
+ }
48
53
else if (data > root -> data )
54
+ {
55
+ // If it isn't null and the input key is greater than the root key,
56
+ // insert in the right leaf
49
57
root -> right = insert (root -> right , data );
50
- // If it isn't null and the input key is lower than the root key, insert in
51
- // the left leaf
58
+ }
52
59
else if (data < root -> data )
60
+ { // If it isn't null and the input key is lower than the root key, insert
61
+ // in the left leaf
53
62
root -> left = insert (root -> left , data );
63
+ }
54
64
// Returns the modified tree
55
65
return root ;
56
66
}
57
67
58
- // Utilitary procedure to find the greatest key in the left subtree
68
+ /** Utilitary procedure to find the greatest key in the left subtree
69
+ * @param root pointer to parent node
70
+ * @returns pointer to parent node
71
+ */
59
72
node * getMax (node * root )
60
73
{
61
74
// If there's no leaf to the right, then this is the maximum key value
62
- if (root -> right == NULL )
63
- return root ;
64
- else
65
- root -> right = getMax (root -> right );
75
+ if (root -> right != NULL )
76
+ {
77
+ return getMax (root -> right );
78
+ }
79
+ return root ;
66
80
}
67
81
68
- // Deletion procedure, which searches for the input key in the tree and removes
69
- // it if present
82
+ /** Deletion procedure, which searches for the input key in the tree and removes
83
+ * it if present
84
+ * @param root pointer to parent node
85
+ * @param data value to search for int the node
86
+ * @returns pointer to parent node
87
+ */
70
88
node * delete (node * root , int data )
71
89
{
72
90
// If the root is null, nothing to be done
73
91
if (root == NULL )
92
+ {
74
93
return root ;
75
- // If the input key is greater than the root's, search in the right subtree
94
+ }
76
95
else if (data > root -> data )
96
+ { // If the input key is greater than the root's, search in the right
97
+ // subtree
77
98
root -> right = delete (root -> right , data );
78
- // If the input key is lower than the root's, search in the left subtree
99
+ }
79
100
else if (data < root -> data )
101
+ { // If the input key is lower than the root's, search in the left subtree
80
102
root -> left = delete (root -> left , data );
81
- // If the input key matches the root's, check the following cases
82
- // termination condition
103
+ }
83
104
else if (data == root -> data )
84
105
{
85
- // Case 1: the root has no leaves, remove the node
106
+ // If the input key matches the root's, check the following cases
107
+ // termination condition
86
108
if ((root -> left == NULL ) && (root -> right == NULL ))
87
- {
109
+ { // Case 1: the root has no leaves, remove the node
88
110
free (root );
89
111
return NULL ;
90
112
}
91
- // Case 2: the root has one leaf, make the leaf the new root and remove
92
- // the old root
93
113
else if (root -> left == NULL )
94
- {
114
+ { // Case 2: the root has one leaf, make the leaf the new root and
115
+ // remove
116
+ // the old root
95
117
node * tmp = root ;
96
118
root = root -> right ;
97
119
free (tmp );
@@ -104,10 +126,10 @@ node *delete (node *root, int data)
104
126
free (tmp );
105
127
return root ;
106
128
}
107
- // Case 3: the root has 2 leaves, find the greatest key in the left
108
- // subtree and switch with the root's
109
129
else
110
- {
130
+ { // Case 3: the root has 2 leaves, find the greatest key in the left
131
+ // subtree and switch with the root's
132
+
111
133
// finds the biggest node in the left branch.
112
134
node * tmp = getMax (root -> left );
113
135
@@ -120,30 +142,55 @@ node *delete (node *root, int data)
120
142
return root ;
121
143
}
122
144
123
- // Search procedure, which looks for the input key in the tree and returns 1 if
124
- // it's present or 0 if it's not in the tree
145
+ /** Search procedure, which looks for the input key in the tree and returns 1 if
146
+ * it's present or 0 if it's not in the tree
147
+ * @param root pointer to parent node
148
+ * @param data value to store int he new node
149
+ * @returns 0 if value not found in the nodes
150
+ * @returns 1 if value was found
151
+ */
125
152
int find (node * root , int data )
126
153
{
127
154
// If the root is null, the key's not present
128
155
if (root == NULL )
156
+ {
129
157
return 0 ;
130
- // If the input key is greater than the root's, search in the right subtree
158
+ }
131
159
else if (data > root -> data )
160
+ {
161
+ // If the input key is greater than the root's, search in the right
162
+ // subtree
132
163
return find (root -> right , data );
133
- // If the input key is lower than the root's, search in the left subtree
164
+ }
134
165
else if (data < root -> data )
166
+ {
167
+ // If the input key is lower than the root's, search in the left subtree
135
168
return find (root -> left , data );
136
- // If the input and the root key match, return 1
169
+ }
137
170
else if (data == root -> data )
171
+ {
172
+ // If the input and the root key match, return 1
138
173
return 1 ;
174
+ }
175
+ else
176
+ { // unknown result!!
177
+ return 0 ;
178
+ }
139
179
}
140
180
141
- // Utilitary procedure to measure the height of the binary tree
181
+ /** Utilitary procedure to measure the height of the binary tree
182
+ * @param root pointer to parent node
183
+ * @param data value to store int he new node
184
+ * @returns 0 if value not found in the nodes
185
+ * @returns height of nodes to get to data from parent node
186
+ */
142
187
int height (node * root )
143
188
{
144
189
// If the root is null, this is the bottom of the tree (height 0)
145
190
if (root == NULL )
191
+ {
146
192
return 0 ;
193
+ }
147
194
else
148
195
{
149
196
// Get the height from both left and right subtrees to check which is
@@ -154,27 +201,40 @@ int height(node *root)
154
201
// The final height is the height of the greatest subtree(left or right)
155
202
// plus 1(which is the root's level)
156
203
if (right_h > left_h )
204
+ {
157
205
return (right_h + 1 );
206
+ }
158
207
else
208
+ {
159
209
return (left_h + 1 );
210
+ }
160
211
}
161
212
}
162
213
163
- // Utilitary procedure to free all nodes in a tree
214
+ /** Utilitary procedure to free all nodes in a tree
215
+ * @param root pointer to parent node
216
+ */
164
217
void purge (node * root )
165
218
{
166
219
if (root != NULL )
167
220
{
168
221
if (root -> left != NULL )
222
+ {
169
223
purge (root -> left );
224
+ }
170
225
if (root -> right != NULL )
226
+ {
171
227
purge (root -> right );
228
+ }
172
229
free (root );
230
+ root = NULL ; // reset pointer
173
231
}
174
232
}
175
233
176
- // Traversal procedure to list the current keys in the tree in order of value
177
- // (from the left to the right)
234
+ /** Traversal procedure to list the current keys in the tree in order of value
235
+ * (from the left to the right)
236
+ * @param root pointer to parent node
237
+ */
178
238
void inOrder (node * root )
179
239
{
180
240
if (root != NULL )
@@ -185,7 +245,8 @@ void inOrder(node *root)
185
245
}
186
246
}
187
247
188
- void main ()
248
+ /** Main funcion */
249
+ int main ()
189
250
{
190
251
// this reference don't change.
191
252
// only the tree changes.
@@ -218,7 +279,9 @@ void main()
218
279
root = delete (root , data );
219
280
}
220
281
else
282
+ {
221
283
printf ("Tree is already empty!\n" );
284
+ }
222
285
break ;
223
286
224
287
case 3 :
@@ -240,4 +303,6 @@ void main()
240
303
241
304
// deletes the tree from the heap.
242
305
purge (root );
306
+
307
+ return 0 ;
243
308
}
0 commit comments