前言
T_T此专栏用于记录数据结构及算法的(痛苦)学习历程,便于日后复习(这种事情不要啊)。所用教材为《数据结构 C语言版 第2版》严蔚敏。
一、二叉树遍历的定义(官方版)
根据二叉树的递归定义可知,二叉树是由3个基本单元组成:根结点、左子树和右子树。因此,若能依次遍历这三部分,便是遍历了整个二叉树。假如从 L、D、R 分别表示遍历左子树、访问根结点和遍历右子树,则有DLR、LDR、LRD、DRL、RDL、RLD这6种遍历二叉树的方案。若限定先左后右,则只有前3种情况,分别称之为先(根)序遍历、中(根)序遍历和后(根)序遍历。
先序遍历二叉树的操作定义:若二叉树为空,则空操作;否则(1)访问根结点;(2)先序遍历左子树;(3)先序遍历右子树。
中序遍历二叉树的操作定义:若二叉树为空,则空操作;否则(1)中序遍历左子树;(2)访问根结点;(3)中序遍历右子树。
后序遍历二叉树的操作定义:若二叉树为空,则空操作;否则(1)后序遍历左子树;(2)后序遍历右子树;(3)访问根结点。
二、二叉树遍历的定义(胡乱理解版)
先序遍历二叉树:根据每个结点第一次访问到(我来了)的次序访问结点。
中序遍历二叉树:根据每个结点第二次访问到(我又来了)的次序访问结点。
后序遍历二叉树:根据每个结点第三次访问到(我又又来了)的次序访问结点。
三、二叉树遍历的递归实现
//先序遍历
status PreOrderTraverse(BiTree T)
{
if (T == NULL)return ok;
VisitT(T); //希望对每个结点进行的操作
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
//中序遍历
status InOrderTraverse(BiTree T)
{
if (T == NULL)return ok;
InOrderTraverse(T->lchild);
VisitT(T); //希望对每个结点进行的操作
InOrderTraverse(T->rchild);
}
//后序遍历
status PostOrderTraverse(BiTree T)
{
if (T == NULL)return ok;
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
VisitT(T); //希望对每个结点进行的操作
}
四、二叉树遍历的非递归实现
二叉树遍历的递归实现虽然语句简单,但难以理解,且当结点数量较多时,递归会占用大量内存空间。为此,我们需要了解二叉树遍历的非递归实现。
下面给出中序遍历的非递归实现代码。有关栈的操作见栈的实现。注意栈的结点数据域类型应为BiTree
或BTNode*
。
void InOrderTraverse_unrec(BiTree T)
{
SqStack S;
CreatStack(S); //创建空栈
BiTree p = T;
while (p || !Stackempty(S)) //如果p和栈都空则终止循环
{
if (p)
{
//栈顶元素始终是p的parent节点
Push(S, p); //入栈
p = p->lchild;
}
else
{
Pop(S, p); //出栈,把栈顶元素弹出给p,此时变成了原p的parent
//此时p的左孩子为空,根据in-oder规则,输出根节点p,然后再以相同的方式遍历他的右孩子
printf("%c", p->data);
p = p->rchild; //输出根节点后,遍历其右子树
}
}
}
五、二叉树层次遍历的非递归实现
除了先中后序三种遍历方式,有时我们还使用层次遍历的方式遍历二叉树。这种方式按照 “从上到下,从左到右" 的顺序遍历二叉树, 即先遍历二叉树第一层的结点,然后是第二层的结点,直到最底层的结点, 对每一层的遍历按照从左到右的次序进行。层次遍历不是一个递归过程,其算法的实现可以借助队列这种数据结构。
下面给出具体实现代码。有关队列的操作见队列的实现。注意队列的结点数据域类型应为BiTree
或BTNode*
。
void LevelOrder(BiTree T)
{
BiTree p;
SqQueue qu;
CreatQueue(qu); //创建空队
EntryQ(qu, T); //将根节点入队
while (!Queueempty(qu)) //如果队列空则停止循环
{
OutQ(qu, p); //出队一个结点
printf("%c ", p->data); //输出
if(p->lchild != NULL)EntryQ(qu, p->lchild); //入队左孩子
if(p->rchild != NULL)EntryQ(qu, p->rchild); //入队右孩子
}
}
总结
路漫漫其修远兮,吾将上下而摆烂。(又是划水的一天,water,water,water,water,water…)
有任何疑问和补充,欢迎交流。(但我显然不会T_T)