先序中序重建二叉树

基本思路:
1、先序遍历第一个结点作为根节点。
2、在中序遍历中查找根节点的位置,以此为界将中序遍历序列划分为左右两个序列(左、右子树)。
3、根据左、右子树在中序序列中的结点个数,将先序序列去掉根结点后的序列划分为左、右两个序列,它们分别为左、右子树的先序序列。
4、对左、右子树的先序序列和中序序列递归实施同样方法,直到左、右子树为空。

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

typedef struct TNode
{
    int data;
    struct TNode *lchild,*rchild;
 } TNode,*PTNode;

//先序遍历输出二叉树
void print(PTNode root)
{
    PTNode ptnode = root;
    if(ptnode!=NULL)
    {   
        printf("%d ",ptnode->data);
        print(ptnode->lchild);
        print(ptnode->rchild);  
    }
 } 

//利用先序中序遍历重构二叉树
PTNode rebuild(int *startPreorder,int *endPreorder,int *startInorder,int *endInorder)
{
    int rootvalue = startPreorder[0];
    PTNode root = (PTNode)malloc(sizeof(TNode));
    root->data = rootvalue;
    root->lchild = root->rchild = NULL;

    if(startPreorder == endPreorder)
    {
        if(startInorder == endInorder && *startPreorder == *startInorder)
        {
            return root;
        }
        else
        {
            printf("input error!\n");
            exit(-1);
        }
    }

    //在中序遍历中找根节点的值 
    int *rootInorder = startInorder; 
    while(rootInorder<=endInorder && *rootInorder != rootvalue)
        ++rootInorder;
    if(rootInorder == endInorder && *rootInorder != rootvalue)
    {
        printf("input error!\n");
        exit(-1);
    }

    int leftLength = rootInorder-startInorder;
    int *leftPreorderEnd = startPreorder+leftLength;
    //构建左子树 
    if(leftLength>0)
    {
        root->lchild = rebuild(startPreorder+1,leftPreorderEnd,startInorder,rootInorder-1);
    }
    //构建右子树 
    if(leftLength<endPreorder-startPreorder)
    {
        root->rchild = rebuild(leftPreorderEnd+1,endPreorder,rootInorder+1,endInorder);
    }

    return root;
}
PTNode rebuildTree(int *preorder,int *inorder,int length)
{
    if(preorder == NULL || inorder == NULL || length<=0)
    return NULL;

    return rebuild(preorder,preorder+length-1,inorder,inorder+length-1);
}



int main(int argc, char *argv[]) {
    int pre[] = {1,2,3};
    int in[] = {2,1,3};
    PTNode root = rebuildTree(pre,in,sizeof(pre)/sizeof(pre[0]));
    print(root);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值