【转】二叉树的三种遍历的相互转化——已知先序中序求后序
2015-10-09 21:00
363 查看
/article/2464398.html
题目:
已知二叉树的先序和中序遍历字符串,编程实现输出后序遍历字符串,
如果没有成功输出Failed,最后分析时间和空间复杂度。
题目来源:
经典题目,也是网易游戏2011年游戏开发工程师的一道笔试题。
分析:
二叉树的题目基本上都是要用递归的,这题也一样。
而递归的核心是找到结构相同的子问题。
二叉树如下所示:
a
↙ ↘
b c
↙↘ ↘
d e g
前序: abdecg
中序: dbeacg
由前序的第一个a,可以把树分为两个部分,左子树和右子树。
在中序序列中找到a,左边部分则是左子树的中序,右边则是右子树的中序,
同样前序a的后面紧跟着左子树的前序和右子树的前序。
则问题可分解为两个结构相同的小问题。
1,先求左子树的后序;
2,求右子树的后序;
3,再将左子树和右子树的后序串起来,最后加上本身节点即可。
代码:
[cpp] view plaincopyprint?
#include <string>
#include <iostream>
using namespace std;
string FindPostOrder( string pre_order, string in_order );
int _tmain(int argc, _TCHAR* argv[])
{
string pre_order, in_order, post_order;
cin >> pre_order >> in_order;
cout << FindPostOrder( pre_order, in_order );
return 0;
}
string FindPostOrder( string pre_order, string in_order )
{
if( pre_order.length() != in_order.length() ) //前序中序元素个数不相等出错
{
cout << "Failed" << endl;
exit(1);
}
if( pre_order.length() == 1 ) //递归终止
{
if( pre_order != in_order ) //一个元素时前序中序不相等
{
cout << "Failed" <<endl;
exit(1);
}
return pre_order;
}
if( pre_order.length() == 0) //前序为空时,后序也为空
return string();
char node = pre_order[0]; //取第一个元素
int index = in_order.find( node ); //找到其在中序中的位置
if( index == string::npos ) //没有找到,则出错
{
cout << "Failed" <<endl;
exit(1);
}
int len = pre_order.length();
//左子树的后序
string left_part = FindPostOrder( pre_order.substr(1,index), in_order.substr(0,index) );
//右子树的后序
string right_part = FindPostOrder( pre_order.substr(1+index, len-index-1), in_order.substr(1+index,len-index-1) );
return left_part+right_part+node; //串联起来
}
题目:
已知二叉树的先序和中序遍历字符串,编程实现输出后序遍历字符串,
如果没有成功输出Failed,最后分析时间和空间复杂度。
题目来源:
经典题目,也是网易游戏2011年游戏开发工程师的一道笔试题。
分析:
二叉树的题目基本上都是要用递归的,这题也一样。
而递归的核心是找到结构相同的子问题。
二叉树如下所示:
a
↙ ↘
b c
↙↘ ↘
d e g
前序: abdecg
中序: dbeacg
由前序的第一个a,可以把树分为两个部分,左子树和右子树。
在中序序列中找到a,左边部分则是左子树的中序,右边则是右子树的中序,
同样前序a的后面紧跟着左子树的前序和右子树的前序。
则问题可分解为两个结构相同的小问题。
1,先求左子树的后序;
2,求右子树的后序;
3,再将左子树和右子树的后序串起来,最后加上本身节点即可。
代码:
[cpp] view plaincopyprint?
#include <string>
#include <iostream>
using namespace std;
string FindPostOrder( string pre_order, string in_order );
int _tmain(int argc, _TCHAR* argv[])
{
string pre_order, in_order, post_order;
cin >> pre_order >> in_order;
cout << FindPostOrder( pre_order, in_order );
return 0;
}
string FindPostOrder( string pre_order, string in_order )
{
if( pre_order.length() != in_order.length() ) //前序中序元素个数不相等出错
{
cout << "Failed" << endl;
exit(1);
}
if( pre_order.length() == 1 ) //递归终止
{
if( pre_order != in_order ) //一个元素时前序中序不相等
{
cout << "Failed" <<endl;
exit(1);
}
return pre_order;
}
if( pre_order.length() == 0) //前序为空时,后序也为空
return string();
char node = pre_order[0]; //取第一个元素
int index = in_order.find( node ); //找到其在中序中的位置
if( index == string::npos ) //没有找到,则出错
{
cout << "Failed" <<endl;
exit(1);
}
int len = pre_order.length();
//左子树的后序
string left_part = FindPostOrder( pre_order.substr(1,index), in_order.substr(0,index) );
//右子树的后序
string right_part = FindPostOrder( pre_order.substr(1+index, len-index-1), in_order.substr(1+index,len-index-1) );
return left_part+right_part+node; //串联起来
}
相关文章推荐
- android模仿58筛选下拉框(PopupWindow实现)
- 四元数和旋转矩阵
- Codeforces Round #317 (Div. 2) 572B. Order Book 排序+贪心
- java枚举
- maven3创建多模块web项目
- 生成窗口最大值数组
- Servlet读取头信息
- 基本属性与特殊属性
- C语言用数组完成线性表得增删
- UINavigationController+storyboard
- 综合8种子排序算法总结和比较
- readn writen readline函数源代码
- CSDN停站公告
- 翻转单词顺序列(剑指offer) 反转字符串的应用
- django model filter distinct
- POJ 1862 Stripies
- 输出从1~n的全排列
- 淘宝穿衣搭配算法_方案二
- 第二章 采购与供应中的增值
- 关于数组的一些心得