版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28788687/article/details/78221350
1.算法基本思路
我们不妨在先序遍历的启示下,定义一种新的遍历规则:我们将 一棵树分为根节点, 左子树, 右子树.访问左节点后,访问根节点,再访问右子树。
- 跟先序遍历一样,访问节点L后,并不是直接访问节点R,而是递归的访问以节点L为根节点的子树。
2.算法基本实现
void Inorder_Travel( Tree T )
{
if( T != NULL )
{
PreTravel(T ->Left );
printf("%d ",T ->data );
PreTravel( T ->Right );
}
}
- 如果我们算法printf暂时“抹去”printf语句的话,我们会看到,先序遍历算法与中序遍历竟会’完全一样‘。不久之后,我们甚至将看见后序遍历算法忽略printf语句之后,同样与前两者,没有什么区别。
- 跟先序遍历一样,中序遍历算法在时间复杂度以达到最优,因此我们思考的重点应该是如何在常系数方面改进算法.一种可行方案是考虑到上述算法是一个递归算法,因此我们可以将其转换为非递归算法。
3.非递归版本
观察本文中序遍历算法的基本思路中第二幅图,不难将访问路径总结为下列过程 : 沿着左侧路径至底向上遍历对应的右子树。
我们同样选择用栈来保存节点的信息,以使得当我们从沿某一左路径向下之后,我们能沿着这条路径向上遍历对应的右子树。具体代码
void InorderVisit( Root T )
{
PtrTreeNode t = T;
while( TRUE ){
while( t != NULL )
{
//暂时储存左路径信息
Push( t );
t = t ->left;
}
if( Isempty() ) return;
//开始访问右子树,并转向右子树
t = Pop();
printf("%d ",t ->data);
t = t ->right;
}
}
- 如果你仔细的将该代码与先序遍历代码,相比较你会发现他们两者竟如此相似,究其原因在于他们递归路径没有区别,他们之间的差异在于访问节点的时机不同而已。