-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbtreetraverse.c
195 lines (172 loc) · 6.34 KB
/
btreetraverse.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
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
/* Copyright © 2021-2023 Chee Bin HOH. All rights reserved.
*
* Depth first search, preorder, inorder and postorder in iterative way.
*/
#include "btreetraverse.h"
#include "btree.h"
#include <stdio.h>
#include <stdlib.h>
/* A post order traverse in iterative way:
*
* If we are at a node, we will process left child node (if any), and then
* process right child node (if any), and then the node that owns the left and
* right child nodes. When we are in a child node, we will apply same processing
* ordering (left, right and node itself).
*
* It is a depth first approach starting at the left branch, so we will further
* deeper on the left and then to right branch, and apply the same left, right
* and node ordering, then go up one level to another right branch and apply the
* same left, right and node ordering.
*
* How to do it in none-recursive fashion?
*
* - we do none-recursive loop to traverse the tree.
* - we start at the root, if root is not NULL, we continue the loop.
* - if root->left is not NULL, we need to process left branch and then
* backtrack to right branch and then parent node of the branches, so we store
* root (parent node) in rightPendingList (the name indicates that right branch
* is pending to be processed), and then assign root->left to be new root and
* continue the loop.
* - if root->left is NULL, but root->right is not NULL, then we need to process
* the right node and then back to the root later, let store the root in
* topPendingList so we want to backtrack to it after we exhaust the right
* branch, we assign root->right to be new root and continue the loop.
* - if we have exhausted left or right branches of a node (root), then we need
* to bracktrack, so the backtracking is logic as that
* -- if topPendingList is not empty, and we peek at the top (of
* topPendingList), and if the top's right branch is equal to the root now, then
* we are at the right branch of top, then we pop out top from topPendingList,
* and assigning it to the root, and continue the loop, eventually we are
* backtracking from right branch backward to higher branch of the tree.
*
* we will continue that backtracking from right branch up the tree until
* we are reach a top from topPendingList that it right branch is not equal to
* root.
*
* -- once we backtrack enough from right branch either by exhausting the
* topPendingList, or reach top of the topPendingList that its right branch is
* not equal to root, then we will process rightPendingList if its node has
* right branch.
*
* rightPendingList is to store node that its right branch is pending to be
* processed. topPendingList is to store node that its left branch has
* processed, right branch is now in process, but its node is not yet processed.
*/
void postOrderTraversal(struct TreeNode *root) {
struct TreeNode *rightPendingList[100];
struct TreeNode *topPendingList[100];
int rightPendingIndex = 0;
int topPendingIndex = 0;
int count = 0; // a fail-safe to prevent infinite loop
int start = 0;
while (NULL != root && count < 1000) {
if (NULL != root->left) {
rightPendingList[rightPendingIndex++] = root;
root = root->left;
} else if (NULL != root->right) {
topPendingList[topPendingIndex++] = root;
root = root->right;
} else {
if (start)
printf(", ");
printf("%d", root->val);
start = 1;
while (topPendingIndex > 0 &&
topPendingList[topPendingIndex - 1]->right == root) {
root = topPendingList[--topPendingIndex];
printf(", %d", root->val);
}
root = NULL;
while (rightPendingIndex > 0 &&
((root = rightPendingList[--rightPendingIndex])->right) == NULL) {
printf(", %d", root->val);
root = NULL;
}
if (NULL != root) {
topPendingList[topPendingIndex++] = root;
root = root->right;
}
}
count++;
}
if (count > 0)
printf("\n");
}
/* An in order traversal logic:
*
* We process left branch of a node, the node and then right branch, we traverse
* tree in depth first approach, so if there is left branch, we will proceed
* further left as far as possible, then the node (in bottom) and then right
* branch, when we are in right branch, we will repeat above.
*
* It is simple than postorder logic that we only need a topPendingList that
* stores a list of node that we want to process after processing the left
* branch.
*/
void inOrderTraversal(struct TreeNode *root) {
struct TreeNode *topPendingList[100];
int topPendingListIndex = 0;
int count = 0;
int start = 0;
while (NULL != root && count < 1000) {
count++;
if (NULL != root->left) {
topPendingList[topPendingListIndex++] = root;
root = root->left;
} else {
if (start)
printf(", ");
printf("%d", root->val);
start = 1;
if (NULL != root->right) {
root = root->right;
} else if (topPendingListIndex > 0) {
do {
root = topPendingList[--topPendingListIndex];
printf(", %d", root->val);
root = root->right;
} while (NULL == root && topPendingListIndex > 0);
} else {
root = NULL;
}
}
}
if (count > 0)
printf("\n");
}
/* A pre order traversal logic:
*
* We process the node, the left branch, and then right branch, we traverse tree
* in depth first approach, so if there is left branch, we will proceed further
* left as far as possible, and then right branch, when we are in right branch,
* in each next level, we will repeat above.
*
* It is simple than postorder logic that we only need a rightPendingList that
* stores a list of right branch node that we want to process after processing
* the left branch.
*/
void preOrderTraversal(struct TreeNode *root) {
struct TreeNode *rightPendingList[100];
int rightPendingListIndex = 0;
int count = 0;
while (NULL != root && count < 1000) {
count++;
if (count > 1)
printf(", ");
printf("%d", root->val);
if (NULL != root->left) {
if (NULL != root->right)
rightPendingList[rightPendingListIndex++] = root->right;
root = root->left;
} else if (NULL != root->right) {
root = root->right;
} else {
if (rightPendingListIndex > 0)
root = rightPendingList[--rightPendingListIndex];
else
root = NULL;
}
}
if (count > 0)
printf("\n");
}