已知二叉树的中序和前序(或者后序)序列求解树

这种题一般有二种形式,共同点是都已知中序序列。如果没有中序序列,是无法唯一确定一棵树的,证明略。

一、已知二叉树的前序序列和中序序列,求解树。  相关题目

1、确定树的根节点。树根是当前树中所有元素在前序遍历中最先出现的元素。

2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点左边和右边都为空,则根节点已经为叶子节点。

3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。

二、已知二叉树的后序序列和中序序列,求解树。

1、确定树的根。树根是当前树中所有元素在后序遍历中最后出现的元素。

2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点左边和右边都为空,则根节点已经为叶子节点。

3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。

举例说明:根据已知求解二叉树

中序序列 HLDBEKAFCG
后序序列 LHDKEBFGCA

1、在后序序列LHDKEBFGCA中最后出现的元素为A,HLDBEK|A|FCG
2、在后序序列LHDKEB中最后出现的元素为B,HLD|B|EK|A|FCG
3、在后序序列LHD中最后出现的元素为D,HL|D|B|EK|A|FCG
4、在后序序列LH中最后出现的元素为H,H|L|D|B|EK|A|FCG
5、在后序序列KE中最后出现的元素为E,H|L|D|B|E|K|A|FCG

5、在后序序列FGC中最后出现的元素为C,H|L|D|B|E|K|A|F|C|G
6、所有元素都已经定位,二叉树求解完成。

                 A
              /     \
             B       C
            / \     /  \
           D  E     F   G
          /    \
         H      K                    
          \                         
           L                     
代码如下:
/*
     功能: 1.利用树的前序和中序序列创建树
           2.利用树的后序和中序序列创建树
 */
 #include <iostream>
 #include <cstring>
 using namespace std;

 char pre[50] = "ABDHLEKCFG";        //前序序列
 char mid[50] = "HLDBEKAFCG";        //中序序列
 char post[50] = "LHDKEBFGCA";        //后序序列

 typedef struct _Node
 {
     char v;
     struct _Node *left;
     struct _Node *right;
     _Node(){left=NULL;right=NULL;}
 }Node, *PNode;

 void PostTravelTree(PNode pn);        //树的后序递归遍历
 void PreTravelTree(PNode pn);        //树的前序递归遍历
 void PreMidCreateTree(PNode &pn, int i, int j, int len);        //利用前序中序序列创建树
 void PostMidCreateTree(PNode &pn, int i, int j, int len);        //利用后序中序序列创建树
 int Position(char c);                //确定c在中序序列mid中的下标,假设树的各个节点的值各不相同


 int main()
 {
     PNode root1 = NULL, root2= NULL;

     PreMidCreateTree(root1, 0, 0, strlen(mid));
     PostTravelTree(root1); cout<<endl;
     PostMidCreateTree(root2, strlen(post)-1, 0, strlen(mid));
     PreTravelTree(root2); cout<<endl;

     return 0;
 }


 int Position(char c)
 {
     return strchr(mid,c)-mid;
 }


 /*  利用前序中序序列创建树,参考了http://hi.baidu.com/sulipol/blog/item/f01a20011dcce31a738b6524.html
  *        i: 子树的前序序列字符串的首字符在pre[]中的下标
  *        j: 子树的中序序列字符串的首字符在mid[]中的下标
  *      len: 子树的字符串序列的长度
  */
 void PreMidCreateTree(PNode &pn, int i, int j, int len)
 {
     if(len <= 0)
         return;

     pn = new Node;
     pn->v = pre[i];
     int m = Position(pre[i]);
     PreMidCreateTree(pn->left, i+1, j, m-j);            //m-j为左子树字符串长度
     PreMidCreateTree(pn->right, i+(m-j)+1, m+1, len-1-(m-j));    //len-1-(m-j)为右子树字符串长度
 }


 /*  利用后序中序序列创建树
  *        i: 子树的后序序列字符串的尾字符在post[]中的下标
  *        j: 子树的中序序列字符串的首字符在mid[]中的下标
  *      len: 子树的字符串序列的长度
  */
 void PostMidCreateTree(PNode &pn, int i, int j, int len)
 {
     if(len <= 0)
         return;

     pn = new Node;
     pn->v = post[i];
     int m = Position(post[i]);
     PostMidCreateTree(pn->left, i-1-(len-1-(m-j)), j, m-j);//注意参数:m-j左子树的长度,len-1-(m-j)右子树的长度
     PostMidCreateTree(pn->right, i-1, m+1, len-1-(m-j));
 }


 void PostTravelTree(PNode pn)        //后序递归遍历
 {
     if(pn)
     {
         PostTravelTree(pn->left);
         PostTravelTree(pn->right);
         cout<<pn->v<<" ";
     }
 }


 void PreTravelTree(PNode pn)        //前序递归遍历
 {
     if(pn)
     {
         cout<<pn->v<<" ";
         PreTravelTree(pn->left);
         PreTravelTree(pn->right);
     }
 }

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值