二叉树的遍历
常见的二叉树的遍历有三种方式:前序遍历(根节点,左子树,右子树)
中序遍历(左子树,根节点,右子树)
后序遍历(左子树,右子树,根节点)
每种方式都可以用递归和非递归来实现
一、递归遍历
1.先序遍历:
先访问根节点,再访问左子树,左子树访问完之后,访问右子树
void BTreePrevOrder(BTNode* root)
{
if (root == NULL)
return;
printf("%d ", root->_data);
BTreePrevOrder(root->_left);
BTreePrevOrder(root->_right);
}
2.中序遍历:
先访问左子树,左子树访问完之后,访问根节点,访问右子树
void BTreeInOrder(BTNode* root)
{
if (root == NULL)
return;
BTreeInOrder(root->_left);
printf("%d ", root->_data);
BTreeInOrder(root->_right);
}
3.后序遍历:
先访问左子树,再访问右子树,最后访问根节点
void BTreePostOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
BTreePostOrder(root->_left);
BTreePostOrder(root->_right);
printf("%d ", root->_data);
}
二叉树遍历的递归实现非常简单
二、非递归遍历(用栈来实现)
1.先序遍历
首先打印根节点,将其入栈,判断其左孩子是否为空,若不为空,打印左孩子,将其入栈,重复上述操作,直至左孩子为空。然后取出栈顶元素,将其右孩子当成根节点,重复上述操作。参照下图进行理解。
void BTreePrevOrderNonR(BTNode* root)
{
Stack s;
BTNode* cur = root;
BTNode* top = NULL;
if (root == NULL)
return;
StackInit(&s);
while (cur || StackEmpty(&s) != 0)
{
while (cur)
{
printf("%d ", cur->_data);
StackPush(&s, cur);
cur = cur->_left;
}
top = StackTop(&s);
StackPop(&s);
cur = top->_right;
}
printf("\n");
}
2.中序遍历:
中序遍历与先序遍历过程较为相似,只需要改变printf的位置即可。
void BTreeInOrderNonR(BTNode* root)
{
Stack s;
BTNode* cur = root;
BTNode* top = NULL;
if (root == NULL)
return;
StackInit(&s);
while (cur || StackEmpty(&s) != 0)
{
while (cur)
{
StackPush(&s, cur);
cur = cur->_left;
}
top = StackTop(&s);
printf("%d ", top->_data);
StackPop(&s);
cur = top->_right;
}
printf("\n");
}
3.后序遍历:
后序遍历只需要在中序遍历的基础上判断其右子树是否为空,或者是否已经被访问过即可。
void BTreePostOrderNonR(BTNode* root)
{
Stack s;
BTNode* cur = root;
BTNode* top = NULL;
BTNode* prev = NULL;
if (root == NULL)
return;
StackInit(&s);
while (cur || StackEmpty(&s) != 0)
{
while (cur)
{
StackPush(&s, cur);
cur = cur->_left;
}
top = StackTop(&s);
if (top->_right == NULL || top->_right == prev)
{
printf("%d ", top->_data);
prev = top;
StackPop(&s);
}
else
{
cur = top->_right;
}
}
printf("\n");
}
测试代码:
void TestBinaryTree()
{
DataType a[] = { 1, 2, 3, '#',7,'#', '#', 4, '#', '#', 5, 6, '#', '#','#' };
size_t index = 0;
BTNode* tree = CreateBTree(a, &index, '#');
printf("前序遍历递归 :");
BTreePrevOrder(tree);
printf("\n");
printf("前序遍历非递归:");
BTreePrevOrderNonR(tree);
printf("中序遍历递归 :");
BTreeInOrder(tree);
printf("\n");
printf("中序遍历非递归:");
BTreeInOrderNonR(tree);
printf("后序遍历递归 :");
BTreePostOrder(tree);
printf("\n");
printf("后序遍历非递归:");
BTreePostOrderNonR(tree);
}
运行结果: