二叉树的前序、中序、后序相互变换

(一)已知前序、中序,求后序

1.确定根(前序中第一个结点为根),确定左子树,确定右子树(在中序中,找到前序所示根,其左为左子树,其右为右子树)

2.在左子树中递归

3.在右子树中递归

4.打印当前根

 

题目:

已知二叉树的先序和中序遍历字符串,编程实现输出后序遍历字符串,

如果没有成功输出Failed,最后分析时间和空间复杂度。

 

题目来源:

经典题目,也是网易游戏2011年游戏开发工程师的一道笔试题。

 

分析:

二叉树的题目基本上都是要用递归的,这题也一样。

而递归的核心是找到结构相同的子问题。

二叉树如下所示:

                  a

              ↙   ↘

            b         c

         ↙↘        ↘

       d      e          g

前序: abdecg

中序: dbeacg

由前序的第一个a,可以把树分为两个部分,左子树和右子树。

在中序序列中找到a,左边部分则是左子树的中序,右边则是右子树的中序,

同样前序a的后面紧跟着左子树的前序和右子树的前序。

则问题可分解为两个结构相同的小问题。

1,先求左子树的后序;

2,求右子树的后序;

3,再将左子树和右子树的后序串起来,最后加上本身节点即可。

 

代码:

 

[cpp] view plaincopyprint?

  1. #include <string>  
  2. #include <iostream>  
  3. using namespace std;  
  4.   
  5. string FindPostOrder( string pre_order, string in_order );  
  6.   
  7. int _tmain(int argc, _TCHAR* argv[])  
  8. {  
  9.     string pre_order, in_order, post_order;  
  10.     cin >> pre_order >> in_order;  
  11.     cout << FindPostOrder( pre_order, in_order );  
  12.     return 0;  
  13. }  
  14.   
  15. string FindPostOrder( string pre_order, string in_order )  
  16. {  
  17.     if( pre_order.length() != in_order.length() )   //前序中序元素个数不相等出错  
  18.     {  
  19.         cout << "Failed" << endl;  
  20.         exit(1);  
  21.     }  
  22.   
  23.     if( pre_order.length() == 1 )                //递归终止  
  24.     {  
  25.         if( pre_order != in_order )               //一个元素时前序中序不相等  
  26.         {  
  27.             cout << "Failed" <<endl;  
  28.             exit(1);  
  29.         }  
  30.         return pre_order;  
  31.     }  
  32.   
  33.     if( pre_order.length() == 0)                  //前序为空时,后序也为空  
  34.         return string();  
  35.   
  36.     char node = pre_order[0];                   //取第一个元素  
  37.     int index = in_order.find( node );          //找到其在中序中的位置  
  38.   
  39.     if( index == string::npos )                 //没有找到,则出错  
  40.     {  
  41.         cout << "Failed" <<endl;  
  42.         exit(1);  
  43.     }  
  44.     int len = pre_order.length();  
  45.   
  46.     //左子树的后序  
  47.     string left_part = FindPostOrder( pre_order.substr(1,index), in_order.substr(0,index) );   
  48.     //右子树的后序  
  49.     string right_part = FindPostOrder( pre_order.substr(1+index, len-index-1), in_order.substr(1+index,len-index-1) );  
  50.   
  51.     return left_part+right_part+node; //串联起来  
  52.   
  53. }  
  54.  

(二)已知中序和后序,求前序

1.确定根(后序中最后一个为根),确定左子树,确定右子树

2.打印当前根

3.在左子树中递归

4.在右子树中递归

(三)已知前序和后序,求中序

这样的题是不能得到唯一的二叉树来的!
如:
树A:有结点1,2,3,2是1的左孩子,3是2的右孩子
树B:有结点1,2,3,2是1的右孩子,3是2的左孩子
则A,B的前序都是123,后序都是321,但A的中序是231,B的序是132

 

最后欢迎大家访问我的个人网站: 1024s

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值