在这,关于二叉树的介绍、以及二叉树的遍历的概念,我就不再重述。我的上一篇博客中介绍很详细。要是有些概念忘记的,可以查看。
链接: https://blog.csdn.net/weixin_44585751/article/details/106594699
.
使用递归算法
前序遍历
相关的代码,我在另外一篇博客中有详细解析,可以参考:
https://blog.csdn.net/weixin_44585751/article/details/106636312.
//前序遍历
void preOrder(LPTREE root)
{
if(root != NULL)
{
printf("%c %*s",root->data,4," ");
preOrder(root->lChild);
preOrder(root->rChild);
}
return;
}
中序遍历
//中序遍历
void minOrder(LPTREE root)
{
if(root != NULL)
{
minOrder(root->lChild);
printf("%c\t",root->data);
minOrder(root->rChild);
}
return;
}
//后序遍历
void lastOrder(LPTREE root)
{
if(root != NULL)
{
lastOrder(root->lChild);
lastOrder(root->rChild);
printf("%c %*s",root->data,4," ");
}
return;
}
非递归算法
前序遍历
//前序遍历,非递归算法
void preNo_RecursiveOrder(LPTREE root)
{
// printf("%s\n",__FUNCTION__);
if(root == NULL)
return;
//准备栈
LPTREE stack[10];//存储每次打印结点的位置
int stackTop = -1;//栈顶标记(初始化的结果不是固定的,可以随意写,这只是一个标记而已)
LPTREE Pmove = root;//从根结点开始打印(定义一个移动指针)
while(stackTop != -1 || Pmove)
{
//找到最左边
while(Pmove)
{
printf("%c\t",Pmove->data);//打印走过的结点
stack[++stackTop] = Pmove;//把路径入栈
Pmove = Pmove->lChild;//遍历到最左边
}
//出栈
if(stackTop != -1)
{
Pmove = stack[stackTop--];//获取栈顶元素
Pmove = Pmove->rChild;
}
}
}
中序遍历
//非递归算法,中序遍历
void minNon_RecuriserOrderTree(LPTREE root)
{
if(root == NULL)
return;
LPTREE Pmove = root;//从根结点开始打印
LPTREE stack[10];//定义一个栈空间
int stackTop = -1;//栈顶标记
while(stackTop != -1 || Pmove)
{
//走到最左边,把走过的结点入栈
while(Pmove)
{
stack[++stackTop] = Pmove;
Pmove = Pmove->lChild;
}
//出栈
if(stackTop != -1)
{
Pmove = stack[stackTop--];
printf("%c\t",Pmove->data);
Pmove = Pmove->rChild;
}
}
}
后序遍历
//后序非递归遍历
void lastNon_OrderBinary_Tree(LPTREE root)
{
if(root == NULL)
return;
int stackTop = -1;
LPTREE stack[10];
LPTREE Pmove = root;
LPTREE Pvisit = NULL;//定义一个访问标记
//先入栈,遍历到最左边,找到最左孩子
while(Pmove)
{
stack[++stackTop] = Pmove;
Pmove = Pmove->lChild;
}
//出栈
while(stackTop != -1)
{
Pmove = stack[stackTop--];
//如果有孩子为NULL,或者右孩子已经被访问过,则打印当前节点
if(Pmove->rChild == NULL || Pmove->rChild == Pvisit)
{
printf("%c\t",Pmove->data);
Pvisit = Pmove;
}
//如果右孩子不为NULL,或者右孩子没有被访问,则进行遍历访问
else
{
stack[++stackTop] = Pmove;
Pmove = Pmove->rChild;
while(Pmove)
{
stack[++stackTop] = Pmove;
Pmove = Pmove->lChild;
}
}
}
}
**总结:**我在学习二叉树遍历之前,总觉得它很难,不敢去真正的面对,凡是遇到相关的术语我都敬而远之。就在前俩天,有个学弟问我二叉树的后续非递归遍历该如何求解时,我要说不会吧,太没面子,可真正要给别人讲的话,自己几斤几两心里清楚。于是我就硬着头皮说,这个很简单……你等我俩天时间,我给你写的明明白白的。于是乎,就开始奋笔疾书,头悬梁、锥刺股的加班加点的看。
当我看完之后,发现,其实二叉树的遍历并不是我想的那样难于上青天。如果使用递归算法来解前、中、后序遍历的话,代码很简单,就几行完事了。可是要深刻的理解其深意的话,得花点时间,仔细琢磨琢磨。
教你一个小妙招,不管啥遍历,你找张纸,来支 笔,画一下,思考思考。你能在纸上可以画的出来,那么自然就可以理解了。书上说的,那仅仅是书上的。而只有你理解之后,那才是你自己的东西。
以上代码,有一处出现过一个小Bug,当时怎么也解决不出来。我也请教大神了,也没有给我个啥结果。最后,还是我自己琢磨出来的。
正确:
if(root == NULL)
return;
就这 一句简单代码,我刚开始写的是这样的
错误:
if(root)
return;
就这一行代码,没有加NULL,怎么也运行不出来结果。哈哈,要是你可以的话,多试试几个编译器,看看能不能运行。