二叉树通过前序中序来构建二叉树(炒鸡详细到每一步)

1.首先先说一个想法,也是学校的题,如果二叉树通过前序和中序遍历来生成后序遍历,我们是不是可以通过前中序来输出一个树,然后将树给还原成完整的树,最后再后序遍历这颗树,不就OK了

 

  char preA[]={'A','B','D','E','G','C','H','F'};前序

    char inA[]={'D','B','E','G','A','H','C','F'};中序

这是测试用例

typedef struct TreeNode{
    char data;
    struct TreeNode*left;
    struct TreeNode*right;
}BtNode;
BtNode * creatTreenode(char x){
    BtNode*node=(BtNode*)malloc(sizeof(BtNode));
    node->data=x;
    node->left=node->right=NULL;
    return node;
}

 上面的是基本内容

下面的才是构建二叉树

BtNode *creatBItree(int len,char *preA,char *inA){
    int i;
    if(len==0){
        return NULL;
    }
   BtNode* root=creatTreenode(preA[0]);
    for(i=0;i<len;i++){
        if(inA[i]==root->data)
            break;
    }
    root->left=creatBItree(i, preA+1, inA);
    root->right=creatBItree(len-i-1, preA+i+1, inA+i+1);
    return root;}

1.preA,inA在最开始是先序遍历和中序遍历,然而核心思想就是找他们的交点,不同的交点就是不同的根,从而分割开左右树  第一个交点是A 。i,len(B未找到之前)此时都等于4进入A的左树构建

2.preA+1: [B,D,E,G,C,H,F]从B开始,来寻找B的左树,len和i(D未找到之前)此时等于1,当我找到了B也就是相当于B来视作为根,构建B的左树

3.preA+1: [D,E,G,C,H,F],此时找到了D,因为D是中序的开头,找到D len等于0那么也就是说D的左树为空,那么来看他的右树,(D的左树和右树是都是在D的那一层的),所以右树的1-1=0,D的右节点也是空

4.退到B的地方,B所要找的D和E是在一个面上的,也就是说都退到B的地方,此时i变了,但是len 没变,len依旧是4,但是已经找到B了所以i是1,那么B-i-1,

5.进入B的右节点E的时候,B-i-1为2,也就是说B的右节点有两个 ,preA+1+i是从B的那一层开始(len=4 ,i=1,B被找到)所以从B,D,E,G,C,H,F 开始 +,之后是preA+1+i到了E,in A+i+1 也是从E开始E,G,A,H,C,F

此时写到第四条突然恍然大悟,

i的含义是找到的根节点左子树的节点。

len-i-1的含义其实是当我已经找到根A的时候,我又去找了下一个根B此时A B之间隔着的也就是B的右节点有几个。

遍历左子树的范围是A此时为根节点,先序范围是preA+1~preA+i-1(preA+i-1的含义其实根据那个中序能知道,都加上i那么中序的A左边全是左树,也就是inA+i-1),中序遍历范围是inA~inA+i-1 (这部分属于根节点的左子树)

遍历右子树(他的开始是找到A的右边也就是中序遍历inA+i+1,到inA+length-1,先序遍历的preA+i+1,到preA+length-1)

inA+i是我们要找的根,这时候一左一右,左边为左子树的边界点,右边为右子树的边界点。

构建左子树时候PreA+1就是为了先序遍历的++,

所以这么一步一步分析自然核心思路就会出来,我会以后争取多去写题,做一些更有意义的事情

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

狗哥不是甜妹

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

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

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

打赏作者

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

抵扣说明:

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

余额充值