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

来源:互联网 发布:淘宝网系统 编辑:程序博客网 时间:2024/06/02 11:44


题目描述:

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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
原创粉丝点击