已知先序遍历和中序遍历 如何求后序遍历?

来源:互联网 发布:阿里云主机租用 编辑:程序博客网 时间:2024/06/02 03:19
先序遍历,可记做根左右(二叉树父结点向下先左后右)。
首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树,如果二叉树为空则返回。
中序遍历,左根右。后序遍历,左右根。
 
那已知先序遍历和中序遍历 如何求后序遍历?
举个例子:先序遍历:ABDCF,中序遍历DBAFC。首先先序遍历,根左右,第一个元素必为根节点,则A为根节点。再看中序,左根右,根据A在中序的位置,可知左子树为DB,右子树为FC。然后递归求解DB和FC。先序,B为除去A的第一个元素,即为左子树根。中序,DB,则D为B左。同理,C为根,F为左子树。所以,树为:
 
 
 
 
通过上面总结步骤如下:
①确定树的根节点。通过先序遍历最先出现的元素。
②通过根节点分出左右子树。通过查找根节点在中序中的位置来分出左右子树。
③重复①②步骤,知道求解完成。
 
具体代码如下:
 
int initTree(Tree *root,char *front,char *middle,int num){        in i=0;        root->data = front[0];        if(num==0) return 0;//全部结束        //找到根节点在middle中的位置        for(i=0;i<num;i++)        {                     if(middle[i]==root->data) break;       }       //如果root存在左子树      if(i!=0)      {           root->lchild=new struct TreeNode();           initTree(root->lchild,front+1,middle,i);     }    if(i!=num-1)   {           root->rchild = new struct TreeNode();           initTree(root->rchild,front+i+1,middle+i+1,i);    }    return 1;}

 

下面分析下以上代码,用前面的例子,先序遍历:ABDCF,中序遍历DBAFC:

1、第一层,

先序遍历:A B D C F,

                       ↑                                                

i=0,root->data=front[0]='A',

找A在middle中位置,for(---)  i=2,

因为i!=0,所以,产生新节点,

递归左子树,front+1,

 

2、第二层,第一层:A左分支,num=2

先序: B D  C F ,

            ↑                                                                 

root->data = front[0]='B'

找B在middle中位置,for(---)  i=1,

因为i!=0,所以,产生新节点,

递归左子树,front+1,

 

3、第二层:B 的左分支:,num=1

先序: D  C F ,

            ↑                                                            

root->data = front[0]='D'

找D在middle中位置,for(---)  i=0,

不满足i!=0,也不满足i!=num-1(此时,i=0,num=1)

所以return 1,至 2、第二层

 

4、返回到了上一层:第二层:B,                                                 

此时i=1,num=3

所以不满足if(i!=num-1)

所以return 1,至 1、第一层:A

 

5、第一层:A,i=2,num=5

因为满足if(i!=num-1)

产生新节点,

递归右子树,front+i+1,middle+i+1(即front+3,middle+3,即C,F)

 

6、第一层A的右分支,第二层,num=2

先序:  C F ,      后序:F C 

            ↑                          ↑                      

 

root->data=front[0]='C'

找C在middle中位置,for(---)  i=1,                 

满足if(i!=0)

产生新节点,

递归左子树,front+1,middle

 

8、第二层的左分支,第三层,num=1

先序: F , 后序:F C 

            ↑                 ↑       

root->data=front[0]='F'

找F在middle中位置,for(---)  i=0,

不满足if(i!=0),不满足if(i!=num-1)

返回至上一层C,第6步

 

9、C右子树,

此时i=1,num=2,

不满足if(i!=num-1)

所以return 1,至 1、第一层。

 

return 1

程序结束.

 

通过以上分析,可以看出i与0,num-1的关系所代表的的意义

i:找字符在middle中位置,

而i代表包含当前节点左子树的个数,

若i==0,则说明该节点无左子树。

num代表所以节点个数,

如果i==num-1,则说明该节点在中序遍历时已经是最后一个节点,所以无右子树。

 

该方法的缺点:没有对越界的判断,

 

 

 

 

                           

 

 

 

 

 

 

 

 


0 0