二叉树-中序遍历

来源:互联网 发布:linux文件内容复制 编辑:程序博客网 时间:2024/05/01 16:10

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;    }}
  • 如果你仔细的将该代码与先序遍历代码,相比较你会发现他们两者竟如此相似,究其原因在于他们递归路径没有区别,他们之间的差异在于访问节点的时机不同而已。
原创粉丝点击