已知先序遍历和中序遍历构建二叉树

  • 学数据结构的树时选的实验,因为老师很水不讲代码,比较懵。在网上找了很多代码总是不尽如人意,晚上找到一个比较好的C语言代码(老师要求最好从C语言入手),刚看懂,原作者写的不错,先mark在这里,有空再补。

  • 顺便吐槽下CSDN上的作者,贴代码时最起码让你自己写的测试能正确运行再发表,有的代码都不能编译通过,甚至有的代码free的对象都错了,要找到一个写的准确无误的代码都难…

  • 这是原文代码,原文有图片描述,建议直接看原文(地址在文末)。

#define _CRT_SECURE_NO_WARNINGS  
#include <stdlib.h>  
#include<stdio.h>  
#include <string.h>  

#define  N  100  

typedef struct BiTNode    
{    
    char data;    
    struct BiTNode *lchild,*rchild;    
} BiTNode,* BITree;    

//先序遍历    
void preOrder(BiTNode*root)    
{    
    if (root==NULL)    
    {    
        return;    
    }    
    printf("%c ",root->data);    
    preOrder(root->lchild);    
    preOrder(root->rchild);    
}    
//中序遍历    
void inOrder(BiTNode*root)    
{    
    if (root==NULL)    
    {    
        return;    
    }    
    inOrder(root->lchild);    
    printf("%c ",root->data);    
    inOrder(root->rchild);    
}    

/************************************************************************/  
/* 算法 
1、通过先序遍历找到根结点A,再通过A在中序遍历的位置找出左子树,右子树 
2、在A的左子树中,找左子树的根结点(在先序中找),转步骤1 
3、在A的右子树中,找右子树的根结点(在先序中找),转步骤1                                                                     */  
/************************************************************************/  

//根据先序遍历和中序遍历创建二叉树  
BiTNode* createBiTree(char *pre, char *in, int n)  
{  
    int i = 0;  
    int n1 = 0,n2 = 0;  
    int m1 = 0,m2 = 0;  
    BiTNode*node = NULL;  
    char lpre[N],rpre[N];  
    char lin[N],rin[N];  
    if (n == 0)  
    {  
        return NULL;  
    }  
    node = (BiTNode*)malloc(sizeof(BiTNode));    
    if (node==NULL)    
    {    
        return NULL;    
    }    
    memset(node,0,sizeof(BiTNode));   
    //先序序列的第一个元素必为根结点  
    node->data = pre[0];  
    //根据根结点将中序序列分为左子树和右子数  
    for (i = 0;i<n;i++)  
    {  
        if ((i<=n1)&&(in[i]!=pre[0]))  
        {  
            lin[n1++] = in[i];  
        }  
        else if(in[i]!=pre[0])  
        {  
            rin[n2++] = in[i];  
        }  
    }  
    //根据树的先序序列的长度等于中序序列的长度  
    //且先序遍历是先左子树再后子树,无论先序还是中序 左子树和右子树的长度都是固定的  
    //主意 从i=1开始 因为先序遍历的第一个是根   
    for (i = 1;i < n;i++)  
    {  
        if (i< (n1+1))//n1代表了左子树的长度  
        {  
            lpre[m1++] = pre[i];  
        }  
        else  
        {  
            rpre[m2++] = pre[i];  
        }  
    }  
    node->lchild = createBiTree(lpre,lin,n1);  
    node->rchild = createBiTree(rpre,rin,n2);  

    return node;  
}  

int main()  
{  
    char preNode[N];  
    char inNode[N];  
    int n = 0;  
    char ch;  
    BiTNode* root=NULL;  
    printf("请输入先序序列\n");  
    while((ch = getchar())&&ch!='\n')  
        preNode[n++] = ch;  
    printf("请输入中序序列\n");  
    n = 0;  
    while((ch = getchar())&&ch!='\n')  
        inNode[n++] = ch;  
    root = createBiTree(preNode,inNode,n);  

    printf("先序序列\n");  
    preOrder(root);  
    printf("\n中序序列\n");  
    inOrder(root);  

    system("pause");  
    return 0;  
}  

原文链接:http://blog.csdn.net/bbs375/article/details/52745107

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值