重建二叉树

一.算法背景

给定前序遍历与中序遍历,给定后序遍历与中序遍历,可以确定一棵树;而只给出后序与前序的则不能,原因是只有前序与后序没有办法知道根与左右子树的关系。

二.算法思想

使用递归思想

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
  1. 在前序序列中读取第一个元素作为根节点
  2. 找到根节点在中序序列的位置index
  3. 根据2确定根节点左子树的中序序列与右子树的中序序列,从开始处到index之前的为左子树的中序序列,从index往后到结尾是右子树的中序序列。
  4. 根据2同时确定左子树的前序序列与右子树的前序序列,从第二个元素开始到第index+1个为左子树的前序序列,从第index+2到最后一个为右子树的前序序列
  5. 使用递归重建根节点左子树与右子树
  6. 将左子树与右子树赋值给根节点的左右子树信息

三.算法实现

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;
    }
};
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄