重建二叉树
2015-09-13 16:56
295 查看
重建二叉树
参与人数:1892时间限制:1秒空间限制:32768K
通过比例:19.08%
最佳记录:0 ms|0K(来自 shi_kai)
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
二叉树,先回顾下二叉树的特点:
关于二叉树;n总=n0+n1+n2;n0=n2 + 1 ;so…n总=n1+2*n2+1
每层的最大结点数2^(n-1); 结点总数最大是2^n - 1
关于遍历:先序是:根左右;
中序是:左根右;
后序是:左右根;
一般我们会选择递归的方法来遍历这样代码回简单些;这题也是一样的。
但由于已经给出了函数的框架,所以代码回收到限制;
思路还是递归,方法是分段递归;
学会了方法可以在HDUOJ上做一个,练习一下;
题意是:已知先序和中序输出二叉树的后序!
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1710
249ms AC
然后在提供一种数组递归的,利用指针,会方便很多呢。
46ms AC
参与人数:1892时间限制:1秒空间限制:32768K
通过比例:19.08%
最佳记录:0 ms|0K(来自 shi_kai)
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。二叉树,先回顾下二叉树的特点:
关于二叉树;n总=n0+n1+n2;n0=n2 + 1 ;so…n总=n1+2*n2+1
每层的最大结点数2^(n-1); 结点总数最大是2^n - 1
关于遍历:先序是:根左右;
中序是:左根右;
后序是:左右根;
一般我们会选择递归的方法来遍历这样代码回简单些;这题也是一样的。
但由于已经给出了函数的框架,所以代码回收到限制;
思路还是递归,方法是分段递归;
/* struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; TreeNode *root;*/ class Solution { public: struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) { //判定递归终止条件; if(pre.size() == 0 || in.size() == 0) { return NULL; } //定义Node节点并其求根节点; int root = pre[0]; TreeNode* node = new TreeNode(root); vector<int>::iterator it; //求左右子树的遍历序列; vector<int> preLeft, preRight, inLeft, inRight; //1、求根节点在中序遍历序列中的位置; vector<int>::iterator i; for(it = in.begin(); it != in.end(); it++) { if(root == *it) { i = it; } } //2、求左右子树的中序遍历子序列; int k = 0; for(it = in.begin(); it != in.end(); it++) { if(k == 0) inLeft.push_back(*it); else if(k == 1) inRight.push_back(*it); if(it == i) k = 1; } //3、求左右子树的前序遍历子序列; k = 0; vector<int>::iterator ite; for(it = pre.begin()+1; it != pre.end(); it++) { for(ite = inLeft.begin(); ite != inLeft.end(); ite++) { if(*it == *ite) { preLeft.push_back(*it); k = 1; } } if(k == 0) { preRight.push_back(*it); } k = 0; } //根据遍历序列求出跟的左右节点; node->left = reConstructBinaryTree(preLeft,inLeft); node->right = reConstructBinaryTree(preRight,inRight); //返回节点地址; return node; } };
学会了方法可以在HDUOJ上做一个,练习一下;
题意是:已知先序和中序输出二叉树的后序!
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1710
249ms AC
#include<stdio.h> #include<vector> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; TreeNode *root; class Solution { public: struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) { //判定递归终止条件; if(pre.size() == 0 || in.size() == 0) { return NULL; } //定义Node节点并其求根节点; int root = pre[0]; TreeNode* node = new TreeNode(root); vector<int>::iterator it; //求左右子树的遍历序列; vector<int> preLeft, preRight, inLeft, inRight; //1、求根节点在中序遍历序列中的位置; vector<int>::iterator i; for(it = in.begin(); it != in.end(); it++) { if(root == *it) { i = it; } } //2、求左右子树的中序遍历子序列; int k = 0; for(it = in.begin(); it != in.end(); it++) { if(k == 0) inLeft.push_back(*it); else if(k == 1) inRight.push_back(*it); if(it == i) k = 1; } //3、求左右子树的前序遍历子序列; k = 0; vector<int>::iterator ite; for(it = pre.begin()+1; it != pre.end(); it++) { for(ite = inLeft.begin(); ite != inLeft.end(); ite++) { if(*it == *ite) { preLeft.push_back(*it); k = 1; } } if(k == 0) { preRight.push_back(*it); } k = 0; } //根据遍历序列求出跟的左右节点; node->left = reConstructBinaryTree(preLeft,inLeft); node->right = reConstructBinaryTree(preRight,inRight); //返回节点地址; return node; } }; /***后序遍历***左右根***/ void posOrderRecur(TreeNode *head){ if(head==NULL) return ; posOrderRecur(head->left); posOrderRecur(head->right); if(head==root) printf("%d\n",head->val); else printf("%d ",head->val); } int main() { int n; Solution so; while(scanf("%d",&n)>0) { root=new TreeNode(NULL); vector<int> a,b; int x; for(int i=0;i<n;i++) { scanf("%d",&x); a.push_back(x); } for(int i=0;i<n;i++) { scanf("%d",&x); b.push_back(x); } root=so.reConstructBinaryTree(a,b); TreeNode *h=root; posOrderRecur(h); } return 0; }
然后在提供一种数组递归的,利用指针,会方便很多呢。
46ms AC
#include<stdio.h> #include<vector> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; TreeNode *root; TreeNode *Creat(int *pre,int *in,int n) { TreeNode *s; for(int i=0;i<n;i++) { if(pre[0]==in[i]) { s=new TreeNode(in[i]); //中序历遍中在根节点左边的都是左子树上的 s->left=Creat(pre+1,in,i); //在根节点右边的,都是右子树上的,右子树需要从i+1开始 s->right=Creat(pre+i+1,in+i+1,n-i-1); return s; } } return NULL; } /***后序遍历***左右根***/ void posOrderRecur(TreeNode *head){ if(head==NULL) return ; posOrderRecur(head->left); posOrderRecur(head->right); if(head==root) printf("%d\n",head->val); else printf("%d ",head->val); } int main() { int n; while(scanf("%d",&n)!=EOF) { root=NULL; int a[2005],b[2005]; for(int i=0;i<n;i++) scanf("%d",&a[i]); for(int i=0;i<n;i++) scanf("%d",&b[i]); root=Creat(a,b,n); TreeNode *head=root; posOrderRecur(head); } return 0; }
相关文章推荐
- javascript中字符串的常用方法
- 循环
- Linux字符设备驱动之异步通知
- AWS Region 相关问题
- 比较全的正则表达式
- 数据库存储过程
- ios 生成随机数
- Linux 安装两个mysql服务
- Android源码调试方法
- Android Studio和Eclipse的有关安卓项目的版本号的修改
- 查看服务器 慢 卡 原因 Linux
- 设计原则和设计模式回顾
- Hadoop学习笔记1
- c++stl之逆向迭代器 Reverse Iterators
- 【英语】Bingo口语笔记(80) - 记忆、忘记的表达
- Linux驱动之poll机制
- Oracle数据库 sqlplus命令下 使用backspace键乱码问题!
- 关于继承的新认识
- 10 个免费的服务器监控工具
- Config类(Leap::Config)