• 剑指offer-重建二叉树


    重建二叉树

    一.算法背景

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

    二.算法思想

    使用递归思想

    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;
        }
    };
    
    keep going
  • 相关阅读:
    使用parted 对大容量盘进行分区
    CENTOS7 修改网卡名称为eth[012...],格式
    docker报错
    docker 存储定义成direct-lvm 模式
    Docker存储方式选型建议
    centos install docker setup centos7 安装docker
    docker centos yum 源
    zip 解压脚本
    IaaS,PaaS,Saas 云服务的介绍
    Codeforces Round #589 (Div. 2) D. Complete Tripartite(模拟)
  • 原文地址:https://www.cnblogs.com/MarkKobs-blog/p/10346773.html
Copyright © 2020-2023  润新知