Commit 74a60c72c1256c8a36cbf241d57926ea9a5a5ed2
1 parent
99508f70
add parent in element and implement an iterative in-order traversal with it.
Showing
1 changed file
with
66 additions
and
11 deletions
... | ... | @@ -5,6 +5,7 @@ struct element |
5 | 5 | { |
6 | 6 | int data; |
7 | 7 | |
8 | + struct element * parent; | |
8 | 9 | struct element * left; |
9 | 10 | struct element * right; |
10 | 11 | }; |
... | ... | @@ -13,9 +14,10 @@ struct element * |
13 | 14 | newElement(int data) |
14 | 15 | { |
15 | 16 | struct element * el = malloc(sizeof(struct element)); |
16 | - el->data = data; | |
17 | - el->left = NULL; | |
18 | - el->right = NULL; | |
17 | + el->data = data; | |
18 | + el->parent = NULL; | |
19 | + el->left = NULL; | |
20 | + el->right = NULL; | |
19 | 21 | |
20 | 22 | return el; |
21 | 23 | } |
... | ... | @@ -57,14 +59,16 @@ insertElement(struct element ** tree, int data) |
57 | 59 | while (data != (*node)->data) { |
58 | 60 | if (data < (*node)->data) { |
59 | 61 | if (NULL == (*node)->left) { |
60 | - (*node)->left = newElement(data); | |
62 | + (*node)->left = newElement(data); | |
63 | + (*node)->left->parent = *node; | |
61 | 64 | return; |
62 | 65 | } else { |
63 | 66 | *node = (*node)->left; |
64 | 67 | } |
65 | 68 | } else { |
66 | 69 | if (NULL == (*node)->right) { |
67 | - (*node)->right = newElement(data); | |
70 | + (*node)->right = newElement(data); | |
71 | + (*node)->right->parent = *node; | |
68 | 72 | return; |
69 | 73 | } else { |
70 | 74 | *node = (*node)->right; |
... | ... | @@ -85,15 +89,12 @@ insertElement(struct element ** tree, int data) |
85 | 89 | * This can be NULL wenn calling. |
86 | 90 | */ |
87 | 91 | struct element * |
88 | -findInOrderSuccessor(struct element * tree, struct element ** parent) | |
92 | +findInOrderSuccessor(struct element * tree) | |
89 | 93 | { |
90 | 94 | struct element * node = tree->right; |
91 | 95 | |
92 | - *parent = tree; | |
93 | - | |
94 | 96 | while (NULL != node->left) { |
95 | - *parent = node; | |
96 | - node = node->left; | |
97 | + node = node->left; | |
97 | 98 | } |
98 | 99 | |
99 | 100 | return node; |
... | ... | @@ -126,9 +127,10 @@ deleteElement(struct element ** tree, int data) |
126 | 127 | |
127 | 128 | // case 1: two children |
128 | 129 | if (NULL != node->left && NULL != node->right) { |
129 | - struct element * successor = findInOrderSuccessor(node, &parent); | |
130 | + struct element * successor = findInOrderSuccessor(node); | |
130 | 131 | |
131 | 132 | node->data = successor->data; |
133 | + parent = successor->parent; | |
132 | 134 | node = successor; |
133 | 135 | } |
134 | 136 | |
... | ... | @@ -160,6 +162,55 @@ deleteElement(struct element ** tree, int data) |
160 | 162 | } |
161 | 163 | } |
162 | 164 | |
165 | + | |
166 | +void | |
167 | +traverse(struct element * tree, void (*cb)(int, int)) | |
168 | +{ | |
169 | + struct element * previous = NULL; | |
170 | + struct element * node = tree; | |
171 | + int depth = 1; | |
172 | + | |
173 | + while (tree) { | |
174 | + /* we came from a left node */ | |
175 | + if ((NULL == node->left || previous == node->left) && | |
176 | + previous != node->right) { | |
177 | + | |
178 | + cb(node->data, depth); | |
179 | + previous = node; | |
180 | + | |
181 | + if (NULL != node->right) { | |
182 | + node = node->right; | |
183 | + depth++; | |
184 | + } else { | |
185 | + if (node->parent->right == node) { | |
186 | + break; | |
187 | + } | |
188 | + | |
189 | + node = node->parent; | |
190 | + depth--; | |
191 | + } | |
192 | + } else { | |
193 | + previous = node; | |
194 | + | |
195 | + if (previous == node->left || previous == node->right) { | |
196 | + node = node->parent; | |
197 | + depth--; | |
198 | + } else { | |
199 | + node = node->left; | |
200 | + depth++; | |
201 | + } | |
202 | + } | |
203 | + } | |
204 | +} | |
205 | + | |
206 | +void printElement(int data, int depth) | |
207 | +{ | |
208 | + char format[250]; | |
209 | + | |
210 | + sprintf(format, "%% %dd(%%d)\n", depth * 3); | |
211 | + printf(format, data, depth); | |
212 | +} | |
213 | + | |
163 | 214 | /** |
164 | 215 | * ======================================================================= |
165 | 216 | */ |
... | ... | @@ -196,6 +247,10 @@ main(int argc, char * argv[]) |
196 | 247 | printf("5: 0x%p\n", findElement(root, 5)); |
197 | 248 | printf("6: 0x%p\n\n", findElement(root, 6)); |
198 | 249 | |
250 | + puts ("traverse"); | |
251 | + traverse(root, printElement); | |
252 | + puts ("\n"); | |
253 | + | |
199 | 254 | puts ("delete 5 (one child on both sides):\n"); |
200 | 255 | deleteElement(&root, 5); |
201 | 256 | printf("R: 0x%p\n", root); | ... | ... |
Please
register
or
login
to post a comment