从前序和后序遍历序列,并不能 唯一确定一棵二叉树。
从前序 和中序遍历 或 中序和后序遍历序列 可以唯一确定一棵二叉树。
一、从前序和中序遍历序列构造二叉树
1.题目:
Leetcode 105:给定一棵树的前序遍历 preorder
与中序遍历 inorder
。请构造二叉树并返回其根节点。
2.解析:
例如:preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
3.代码实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return build(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
}
TreeNode* build(vector<int>& preorder,int l1, int r1,vector<int>& inorder,int l2, int r2)
{
//递归终止条件
if(l1 > r1) return nullptr;
TreeNode* root = new TreeNode(preorder[l1]);
int mid_root_index = 0;
//然后检索,中序遍历中的根节点,然后记录根节点的坐标,并且获取左右子树的长度
while(inorder[mid_root_index]!= root->val) mid_root_index++;
//根据中序,左子树的长度
int leftsize = mid_root_index - l2;
//根据中序,右子树的长度
int rightsize= r2-mid_root_index;
//左子树
root->left = build(preorder,l1+1,l1+leftsize,inorder,l2,mid_root_index);
//右子树
root->right = build(preorder,l1+leftsize+1,r1,inorder,mid_root_index+1,r2);
return root;
}
};
二、从中序和后序遍历序列构造二叉树
1.题目:
Leetcode 106: 根据一棵树的中序遍历与后序遍历构造二叉树。
2.解析:
例如:inorder = [9,3,15,20,7] postorder = [9,15,7,20,3]
3.代码实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return build(inorder,0,inorder.size()-1,postorder,0,postorder.size()-1);
}
TreeNode* build(vector<int>& inorder,int l1,int r1, vector<int>& postorder,int l2,int r2)
{
if(l1>r1) return nullptr;
TreeNode* root = new TreeNode(postorder[r2]);
int mid_root_index = 0;
while(inorder[mid_root_index]!= root->val)
{
mid_root_index++;
}
//左子树的大小
int leftsize = mid_root_index - l1;
//右子树的大小
int rightsize = r1- mid_root_index;
//左子树
root->left = build(inorder,l1,mid_root_index-1,postorder,l2,l2+leftsize-1);
//右子树
root->right=build(inorder,mid_root_index+1,r1,postorder,l2+leftsize,r2-1);
return root;
}
};