一、递归过程:
1、先序遍历
void xian(NODE *t)
{
if(t)
{
printf("%c",t->data);
xian(t->lson);
xian(t->rson);
}
}
2、中序遍历
void mid(NODE *t)
{
if(t)
{
mid(t->lson);
printf("%c",t->data);
mid(t->rson);
}
}
3、后序遍历
void hou(NODE *t)
{
if(t)
{
hou(t->lson);
hou(t->rson);
printf("%c",t->data);
}
}
遍历过程分析:
先序,中序,后序遍历过程:遍历过程中经过的路线一样,只是访问各节点的时机不同。
图中在从入口到出口的曲线上用ⓧ,☆,△三种符号分别表示先序,中序,后序访问各节点的时刻。
二、非递归遍历:
堆栈思想
中序遍历
遇到一个结点,就把它压栈,并去遍历它的左子树;
当左子树遍历结束后,从栈顶弹出这个结点并访问它;
然后按其右指针再去中序遍历该结点的右子树。
代码展示
先序遍历
在中序遍历代码的基础上把输出的语句放在Push(S,T);的后面;
后序遍历
void PostOrderTraversal(BinTree BT) {
BinTree T = BT, PrePop = NULL; //PrePop记录上一个Pop出来的结点
Stack S = CreatStack(MaxSize);
while (T || !IsEmpty(S)) {
while (T) { //一直向左将结点压入堆栈
Push(S, T);
T = T->Left;
}
//将Pop的过程改为循环
while (!IsEmpty(S)) { //后序遍历有两种情况可以Pop该结点
T = Pop(S);
if (T->Right == PrePop || T->Right == NULL)//该结点的右结点为空或者上一次Pop的是该结点的右结点
{
printf("%05d", T->Data);
PrePop = T;
}
else { //若不满足以上两种情况 说明该节点右侧节点还未被Pop
Push(S, T); //则将该结点重新压回堆栈
T = T->Right; //然后指向该结点的右节点
break; //退出Pop循环
}
}
}
}