【leetcode】从前序与中序遍历序列构造二叉树

24 篇文章 0 订阅
21 篇文章 0 订阅

根据一棵树的前序遍历与中序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7

 

解题思路:

1、首先需要了解前序遍历和中序遍历的特征,前序遍历的顺序是root--root->left--root->right,中序遍历的顺序是root->left--root--root->right

2、根据两种遍历顺序的特征,使用前序遍历的第一个元素作为root节点,在中序遍历的数组中查找该节点的位置i,那么对于前序遍历的(1~i)个位置是左子树的节点,(i+1~end)个位置是右子树的节点。对于中序遍历的数组来说(0~i-1)个位置是左子树的节点,(i+1~end)是右子数的节点。然后使用递归的方法即可得到整棵树的结构。

提交代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

struct TreeNode* buildTreeCore(int* preorder,int* inorder,int prestart,int preend,int instart,int inend)
{
    printf("1、prestart=%d,preend=%d,instart=%d,inend=%d\n",prestart,preend,instart,inend);
    if(prestart>preend || instart>inend)
    {
        return NULL;
    }    
    struct TreeNode* root=(struct TreeNode*)malloc(sizeof(struct TreeNode));
    root->val=preorder[prestart];
    int i=0;
    for(i=instart;i<=inend;i++)
    {
        if(preorder[prestart]==inorder[i])
        {
            printf("2、preorder[%d]==inorder[%d]\n",prestart,i);
            break;
        }
    }
    if(i==inend+1)//输入preorder和inorder顺序不能生成有效的二叉树
    {
        printf("3、i==inend+1,i=%d,inend+1=%d\n",i,inend+1);
        return NULL;
    }
    root->left=buildTreeCore(preorder,inorder,prestart+1,prestart+i-instart,instart,i-1);
    root->right=buildTreeCore(preorder,inorder,prestart+i-instart+1,preend,i+1,inend);
    return root;
}

struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize) {
    if(preorder==NULL||inorder==NULL || preorderSize<1||preorderSize!=inorderSize)
    {
        return NULL;
    }
    struct TreeNode* root=buildTreeCore(preorder,inorder,0,preorderSize-1,0,inorderSize-1);
    return root;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值