【剑指offer】面试题6:重建二叉树


题目描述:

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列。

根据先序遍历和中序遍历还原二叉树的主要思想:

1、先序遍历序列的第一个元素必定是根节点,可以由此获取二叉树的根节点。

2、根据根节点,在中序遍历序列中查找该节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列必定在根节点的左子树中,而根节点右边的序列必定在右子树中。由此可以知道先序遍历中左子树以及右子树的起止位置。

3、分别对左子树和右子树重复上述的过程,直至所有的子树的起止位置相等时,说明已经到达叶子节点,遍历完毕。


主要函数代码

//传递要一个指针,和一段数据域。指针指向这段区域的根结点
//然后分成两个区域递归调用该函数
int ReCreate(BiTree *t,int begin,int end)
{
    int i;
    int key;

    if(begin>end){      //如果不在范围内,证明没有该结点,赋值空指针并退出。
        *t = NULL;
        return 1;
    }
    key = probuf[++count];
    for(i = begin;i <= end;i++){
        if(inbuf[i] == key)
            break;
    }
    if(i>end){              //当输入的数组不能构成二叉树的时候,返回NO!
        *t = NULL;          //退出的时候,指针为空,否则销毁二叉树时,程序会崩溃
        printf("NO!\n");
        return 0;
    }

    (*t) = (BiTree)malloc(sizeof(BiNode));
    (*t)->key = key;
    int leftbegin = begin;
    int leftend = i-1;
    int rightbegin = i+1;
    int rightend = end;

    i = ReCreate(&((*t)->lchild),leftbegin,leftend);
    if(!i){     //必须判断是否构建过程是吧,然后递归返回,并且还要对又指针进行赋值,悬空的话,销毁二叉树时会崩溃
        (*t)->rchild = NULL;
        return 0;
    }

    ReCreate(&((*t)->rchild),rightbegin,rightend);
    if(!i)
        return 0;

    return 1;
}

主程序

#include <stdio.h>
#include <stdlib.h>

int *probuf;
int *inbuf;
int count = -1;

typedef struct BiNode{
    int key;
    struct BiNode *lchild,*rchild;
}BiNode,*BiTree;

int ReCreate(BiTree *t,int begin,int end);
void PreOrderTraverse(BiTree t);
void InOrderTraverse(BiTree t);
void DestoryTree(BiTree *t);
void PostOrderTraverse(BiTree t);

int main(void)
{
    BiTree T = NULL;
    int n;

    while(scanf("%d",&n)){
        probuf = (int *)malloc(n*sizeof(int));
        inbuf = (int *)malloc(n*sizeof(int));
        for(int i = 0;i<n;i++)
            scanf("%d",probuf+i);
        for(int i = 0;i<n;i++)
            scanf("%d",inbuf+i);
        int i = ReCreate(&T,0,n-1);
        if(!i)
            DestoryTree(&T);
        PostOrderTraverse(T);
        printf("\n");
        free(probuf);
        free(inbuf);
        DestoryTree(&T);
        count = -1;
    }
    return 0;
}

//传递要一个指针,和一段数据域。指针指向这段区域的根结点
//然后分成两个区域递归调用该函数
int ReCreate(BiTree *t,int begin,int end)
{
    int i;
    int key;

    if(begin>end){      //如果不在范围内,证明没有该结点,赋值空指针并退出。
        *t = NULL;
        return 1;
    }
    key = probuf[++count];
    for(i = begin;i <= end;i++){
        if(inbuf[i] == key)
            break;
    }
    if(i>end){              //当输入的数组不能构成二叉树的时候,返回NO!
        *t = NULL;          //退出的时候,指针为空,否则销毁二叉树时,程序会崩溃
        printf("NO!\n");
        return 0;
    }

    (*t) = (BiTree)malloc(sizeof(BiNode));
    (*t)->key = key;
    int leftbegin = begin;
    int leftend = i-1;
    int rightbegin = i+1;
    int rightend = end;

    i = ReCreate(&((*t)->lchild),leftbegin,leftend);
    if(!i){     //必须判断是否构建过程是吧,然后递归返回,并且还要对又指针进行赋值,悬空的话,销毁二叉树时会崩溃
        (*t)->rchild = NULL;
        return 0;
    }

    ReCreate(&((*t)->rchild),rightbegin,rightend);
    if(!i)
        return 0;

    return 1;
}


void PreOrderTraverse(BiTree t)
{
    if(t){
        printf("%d ",t->key);
        PreOrderTraverse(t->lchild);
        PreOrderTraverse(t->rchild);
    }
}

void InOrderTraverse(BiTree t)
{
    if(t){
        InOrderTraverse(t->lchild);
        printf("%d ",t->key);
        InOrderTraverse(t->rchild);
    }
}

void PostOrderTraverse(BiTree t)
{
    if(t){
        PostOrderTraverse(t->lchild);
        PostOrderTraverse(t->rchild);
        printf("%d ",t->key);
    }
}

void DestoryTree(BiTree *t)
{
    if(*t){
        DestoryTree(&((*t)->lchild));
        DestoryTree(&((*t)->rchild));
        free(*t);
        *t = NULL;
    }

}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值