剑指offer---重建二叉树

这篇博客深入探讨了如何通过前序和中序遍历序列来重建二叉树的问题。文章首先分析了在二叉树中前序和中序遍历的特点,指出在中序遍历中根节点通常位于中间,从而可以确定左右子树的边界。接着,通过递归方式详细解释了如何构建左右子树,并提供了相应的C语言实现代码。递归终止条件是子树为空,通过不断递归构造直至构建完整棵二叉树。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目6:重建二叉树(leetcode链接:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/

题目分析

在二叉树中,前序序列的第一个节点是根节点,而在中序序列中根节点一般在序列中间位置。中序序列中,根节点值的左侧的m个值是根节点的左子树根节点右侧的n个值值是根节点的右子树,而在前序序列中根节点后面紧跟着的m个值是左子树,其余的n个值是右子树。因此,可以通过递归利用左右子树的前序和中序序列构建左右子树,从而构建二叉树。

例如,下面的二叉树中,前序序列的第一个值就是1。根据中序序列的特点,可以确定中序序列中根节点的左侧有三个值右侧有四个值(左侧的三个值是左子树的值,右侧的四个值是右子树的值)。

由于在中序遍历序列中,有三个值是左子树的节点值,因此左子树总共有三个节点。同样,在前序遍历序列中根节点后面紧跟的3个值就是左子树的前序序列,后边紧跟的所有值就是右子树的前序遍历序列,这样我们就分别找出了左右子树的前序遍历序列和中序遍历序列。

可以通过左右子树的前序㤡和中序序列以同样的方法递归的构建左右子树,而递归的终止条件就是左右子树均为NULL。

代码描述

typedef struct TreeNode TreeNode;
TreeNode* _buildTree(int* preBegin,int* preEnd,int* inBegin,int* inEnd){
    //创建节点
    TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));
    root->val = preBegin[0];//前序序列的第一个值为根节点
    root->left = root->right = NULL;
    //如果根节点的左右子树为NULL,返回根节点(前序或者中序序列中只有根节点)
        if(preBegin == preEnd){
            return root;
        }
        //在中序序列中找到根节点
        int* inRoot = inBegin;
        while(*inRoot != preBegin[0]){
            inRoot++;
        }
        //创建左子树
        if(inBegin < inRoot)
            root->left = _buildTree(preBegin+1,preBegin+(inRoot - inBegin),inBegin,inRoot-1);
        //创建右子树
        if(inRoot < inEnd){
            root->right = _buildTree(preBegin+(inRoot - inBegin)+1,preEnd,inRoot+1,inEnd);
        }
        return root;
}
struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
    if(preorderSize == 0 && inorderSize == 0){
            return NULL;
        }
    return _buildTree(preorder,preorder+preorderSize-1,inorder,inorder+inorderSize-1);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯狂嘚程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值