剑指offer 面试题6 (根据前序和中序 构建二叉树)

15 篇文章 0 订阅
9 篇文章 0 订阅

这题 浪费了不少时间。。不知道自己现在怎么了。。遇到文件 就总要逃避一下。。唉。。

总的来说非常经典的题了。。就是构建函数 那 尤其是都用指针 太经典了

/*
给出 两个数组 前序和中序 要建立二叉树 返回root节点。。
本来不难的题结果自己看了半天。。唉。。好久不写二叉树了。

*/

#include<iostream>
#include<cstdio>
#include<exception>
#include<cstdlib>
using namespace std;

struct BTNode
{
    int data;
    BTNode * leftchild;
    BTNode * rightchild;
};
BTNode * Construct(int*,int * ,int *,int *);
BTNode * ConstructBT(int * preorder,int * inorder,int len)
{
    if(preorder == NULL || inorder == NULL || len<=0)
        return NULL;
    return Construct(preorder,preorder+len-1,inorder,inorder+len-1);
}
//这个函数的参数非常重要 是四个指针,分别是目前要建立二叉树的前序的头和尾   中序的头和尾
BTNode * Construct(int * startpreorder,int * endpreorder ,int * startinorder, int * endinorder)
{
    BTNode * root =new BTNode();
    int value=startpreorder[0];//前序的第一个是根节点,完成初始化root节点
    root->data=value;
    root->leftchild=root->rightchild=NULL;

    if(startpreorder==endpreorder)//说明只有一个节点 就是根节点了 直接返回
    {
        if(startinorder==endinorder && *startpreorder == *startinorder)
        return root;
        else
        printf("Invalid input");
    }

    //找出root 在 中序中的位置
    int * rootinorder = startinorder;
    while(rootinorder <=endinorder && *rootinorder!=value)
        rootinorder++;

    if(rootinorder == endinorder && *rootinorder!=value)
        printf("Invalid Input\n");
    //leftlenth 是目前要创建的 左子数的节点个数
    int leftlenth=rootinorder-startinorder;
    //这个指针 是要构建的左子树 结束的地方,开始的地方是starpreorder+1 就是原来的根节点的下一个开始到找到中序那里的前一个结束
    int * leftPreorderEnd =startpreorder+leftlenth;

    if(leftlenth>0)//有左子树,继续 递归创建
    {
        root->leftchild=Construct(startpreorder+1,leftPreorderEnd,startinorder,rootinorder-1);
    }

    if(leftlenth<endpreorder-startpreorder)//左边的长度比总的小 也就是有右子树 继续创建
    {
        root->rightchild = Construct(leftPreorderEnd+1,endpreorder,rootinorder+1,endinorder);
    }
    return root;
}

int main()
{
    freopen("/home/gl/in","r",stdin);
    int n,A[20],B[20];
    scanf("%d",&n);
    for(int i=0;i<n;++i)
    scanf("%d",&A[i]);
    for(int i=0;i<n;++i)
    scanf("%d",&B[i]);
    //ConstructBT 返回 root
    BTNode * root = ConstructBT(A,B,n);
    printf("%d\n",root->data);
    while(root!=NULL)
    {
        printf("%d\n",root->data);
          root=root->leftchild;
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值