剑指offer-重建二叉树
重建二叉树
一.算法背景
给定前序遍历与中序遍历,给定后序遍历与中序遍历,可以确定一棵树;而只给出后序与前序的则不能,原因是只有前序与后序没有办法知道根与左右子树的关系。
二.算法思想
使用递归思想
- 在前序序列中读取第一个元素作为根节点
- 找到根节点在中序序列的位置index
- 根据2确定根节点左子树的中序序列与右子树的中序序列,从开始处到index之前的为左子树的中序序列,从index往后到结尾是右子树的中序序列。
- 根据2同时确定左子树的前序序列与右子树的前序序列,从第二个元素开始到第index+1个为左子树的前序序列,从第index+2到最后一个为右子树的前序序列
- 使用递归重建根节点左子树与右子树
- 将左子树与右子树赋值给根节点的左右子树信息
三.算法实现
3.1Python实现
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
if pre and tin:#pre tin都存在
root=pre[0]#根节点
# 判断该值在中序遍历中的位置
i=tin.index(root)
# 左子树的前序序列;右子树的前序序列
lpre=pre[1:i+1]
rpre=pre[i+1:]
# 左子树的中序序列;右子树的中序序列
ltin=tin[0:i]
rtin=tin[i+1:]
tree=TreeNode(root)
tree.left=self.reConstructBinaryTree(lpre,ltin)
tree.right=self.reConstructBinaryTree(rpre,rtin)
return tree
else:#pre tin有一个不存在
return None
pass
按照同样的算法思想,如下给出C++的实现方式。
3.2C++实现
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if (!pre.size()||!vin.size())//如果有一个序列为空
return NULL;
TreeNode* root = new TreeNode(pre[0]);
int i;
for (i = 0; i < vin.size() && vin[i] != pre[0]; i++); // 在中序序列中找到根节点元素的下标赋值为i
vector<int> pre_left, vin_left,pre_right,vin_right; // 分为4个向量
int pre_i = 1;
for (int j = 0; j < vin.size(); j++)
{
if (j < i)
{
vin_left.push_back(vin[j]);
pre_left.push_back(pre[pre_i]);
pre_i++;
}
else if (j>i)
{
vin_right.push_back(vin[j]);
pre_right.push_back(pre[pre_i]);
pre_i++;
}
}
root->left = reConstructBinaryTree(pre_left, vin_left);
root->right = reConstructBinaryTree(pre_right, vin_right);
return root;
}
};
keep going