剑指offer:重建二叉树

题目:

输入某二叉树的前序遍历和中序遍历,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含有重复的数字。

  例如,前序遍历序列:{1,2,3,7,3,5,6,8},中序遍历序列:{4,7,2,1,5,3,8,6}

二叉树遍历基本知识:

  1. 前序遍历:访问根节点,前序遍历左子树,前序遍历右子树
  2. 中序遍历:中序遍历左子树,访问根节点,中序遍历右子树
  3. 后序遍历:后序遍历左子树,后序遍历右子树,访问根节点
根据前序和中序遍历重建二叉树,这里举个例子来说明。

首先,二叉树编号遵循从上到下、从左到右的顺序,如下图中所示

这里写图片描述

前序遍历顺序为:{1,2,4,7,3,5,6,8}

中序遍历顺序为:{4,7,2,1,5,3,8,6}

重建原理:

  1. 由前序遍历可得知根节点为第一位,而在中序遍历中,根节点是隔开左右孩子的,所以根节点的左边为左子树,根节点的右边为右子树;
  2. 由步骤1得出左子树和右子树的长度,分别得出左右子树的前序遍历和中序遍历;
  3. 重复步骤1、2,直到左右子树的长度为0,依次返回寻得的根节点。

注意点:明确二叉树的递归特性,明确遍历方法

代码如下:

class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
         
        int len = pre.size(); //计算遍历长度
         
        if(len == 0)  //长度为0,递归结束
            return NULL;
         
        int root_val = pre[0];  //寻找根节点
        TreeNode* root = new TreeNode(root_val);
         
        int left_len = 0;
 
	//计算左孩子长度
        for(int i=0; i < len ; i++){
            if(vin[i] == root_val){
                left_len = i;
                break;
            }
        }
         
        vector<int> left_pre, left_vin, right_pre, right_vin;
        //将左右子树存入vector,再递归调用重建函数 
        for(int i = 0; i < left_len; i++){
            left_pre.push_back(pre[i+1]);
            left_vin.push_back(vin[i]);
        }
         
        for(int i = left_len + 1 ; i < len; i++){
            right_pre.push_back(pre[i]);
            right_vin.push_back(vin[i]);
        }
         
        root -> left = reConstructBinaryTree (left_pre, left_vin);
                
        root -> right = reConstructBinaryTree (right_pre, right_vin);
         
        return root;
             
    }
};



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值