二叉树的遍历有前序,中序,后序以及层次遍历,其中前序,中序和后序遍历使用递归来写非常简单。
例如
1
2
3
4
5
6
7
|
void tree_preorder_re(TreeNode *node, Tree *tree, void (*visit)(Tree *, TreeNode *))
{
if (!node) return;
visit(tree, node);
tree_preorder_re(node->left, tree, visit);
tree_preorder_re(node->right, tree, visit);
}
|
中序和后序,不过是调整一下visit的位置,如果不用递归的写法,改用栈来实现,其实没有那么直观。
首先按照函数调用的关系,入栈的套路都是一样的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
Stack *s = stack_new();
TreeNode *tNode = tree->root;
while (stack_depth(s) != 0 || tNode)
{
while (tNode != NULL)
{
stack_push(s, tNode);
tNode = tNode->left;
}
if (!stack_is_empty(s))
{
tNode = (TreeNode *)stack_pop(s);
tNode = tNode->right;
}
}
stack_free(s);
|
前序遍历
前序遍历最简单,在节点入栈的时候访问。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
void tree_preorder(Tree *tree, void (*visit)(Tree *, TreeNode *))
{
Stack *s = stack_new();
TreeNode *tNode = tree->root;
while (stack_depth(s) != 0 || tNode)
{
while (tNode != NULL)
{
stack_push(s, tNode);
visit(tree, tNode);
tNode = tNode->left;
}
if (!stack_is_empty(s))
{
tNode = (TreeNode *)stack_pop(s);
tNode = tNode->right;
}
}
stack_free(s);
}
|
中序遍历
在节点出栈的时候访问。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
void tree_inorder(Tree *tree, void (*visit)(Tree *, TreeNode *))
{
Stack *s = stack_new();
TreeNode *tNode = tree->root;
while(stack_depth(s) != 0 || tNode != NULL)
{
while (tNode != NULL)
{
stack_push(s, tNode);
tNode = tNode->left;
}
if (!stack_is_empty(s))
{
tNode = (TreeNode *)stack_pop(s);
visit(tree, tNode);
tNode = tNode->right;
}
}
stack_free(s);
}
|
后序遍历
保证左右节点都访问之后,再访问父节点。
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
|
void tree_postorder(Tree *tree, void (*visit)(Tree *, TreeNode *))
{
Stack *s = stack_new();
TreeNode *tNode = tree->root;
TreeNode *last_visit = NULL;
while(tNode != NULL || !stack_is_empty(s))
{
while (tNode != NULL)
{
stack_push(s, tNode);
tNode = tNode->left;
}
if (!stack_is_empty(s))
{
tNode = (TreeNode *)stack_top(s);
if (tNode->right == NULL || tNode->right == last_visit)
{
stack_pop(s);
last_visit = tNode;
visit(tree, tNode);
tNode = NULL;
}
else
{
tNode = tNode->right;
}
}
}
stack_free(s);
}
|
验证
1
2
3
4
5
6
7
8
9
10
11
12
|
main(251): __debug preorder recursive---
1 2 4 5 3 6 7
main(254): __debug preorder non-recursive---
1 2 4 5 3 6 7
main(257): __debug inorder recursive---
4 2 5 1 6 3 7
main(260): __debug inorder non-recursive---
4 2 5 1 6 3 7
main(263): __debug postorder recursive---
4 5 2 6 7 3 1
main(266): __debug postorder non_ecursive---
4 5 2 6 7 3 1
|