题目
Given preorder and inorder traversal of a tree, construct the binary tree.
算法
从前序中序遍历来重构二叉树
O(n)
这种题一般有二种形式,共同点是都已知中序序列。如果没有中序序列,是无法唯一确定一棵树的。
<1>已知二叉树的前序序列和中序序列,求解树。
1、确定树的根节点。树根是当前树中所有元素在前序遍历中最先出现的元素。
2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点
边和右边都为空,则根节点已经为叶子节点。
3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。
<2>、已知二叉树的后序序列和中序序列,求解树。
1、确定树的根。树根是当前树中所有元素在后序遍历中最后出现的元素。
2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点
边和右边都为空,则根节点已经为叶子节点。
3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。
测试用例:
<1>先序 中序 求 后序
输入:
先序序列:ABCDEGF
中序序列:CBEGDFA
输出后序:CGEFDBA
代码:
#include<iostream>
#include<vector>
#include<stack>
#include <algorithm>
using namespace std;
const int N=0;
//Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
// ps是preoreder的第一个元素下标,is是inoreder的第一个元素的下标
class Solution {
private:
TreeNode *dfs(vector<int> &preorder,vector<int> &inorder,int ps,int is,int len){
if(len<=0)
return NULL;
TreeNode *root=new TreeNode(preorder[ps]);
for(int i=0;i<len;i++){
if(inorder[is+i ]==root->val){
root->left=dfs(preorder,inorder,ps+1,is,i );
root->right=dfs(preorder,inorder,ps+i+1,is+i+1,len-i+1);
break;
}
}
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return dfs(preorder,inorder,0,0,preorder.size());
}
};
int main()
{
vector<int> p={1,2,3};
vector<int> i={1,2,3};
Solution s;
s.buildTree(p,i);
return 0;
}