数据结构二叉树之通过前序和中序恢复二叉树后续方法输出

#include"stdio.h"  
#include"stdlib.h"  
#define max 100  
typedef struct node  
{  
    char data;  
    struct node *rchild,*lchild;  
} tree;  
 
//创建两个字符串数组
void createArray(char q[],char w[])  
{  
    gets(q);  
    gets(w);   
}   
 
//求字符串的长度
int Length(char q[])  
{  
    int i=0;  
    while(*(q+i)!=0)  
        i++;  
    return i;   
}  

//按照先序输出二叉树
void show(tree *t)  
{  
    if(t!=NULL)  
    {  
      
        show(t->lchild);  
        show(t->rchild);  
        printf("%c",t->data);  
    }  
}   
/*思路分析:  
假设我们有这样的一个二叉树  
   1  
  2 3  
 4 5  
那么这个二叉树的前序是这样的:12453  
                中序是这样的:42513  
 
首先,其实大家都知道先找先序的第一个也就是1,然后再去中序中早这个节点  
的位置(我习惯用下标表示),1 2453  
                            425 1 3  
也就是在前序中的1,通过seach函数,找到1所在的下标,也就是3,这样就通过中  
序的序列来将这个二叉树的左右子树分开了,然后,我们不妨这样假设,就是将425这  
个整体看做一个节点,与这并列的就是右节点3了,那么就是假设成这是最简单的一个  
二叉树,只有根节点,和左右节点,这样的话,为根节点申请空间,然后又是为左节点  
申请空间,这里我们重新思考,也就是对425这个整体右节点分析可以知道,425,又是  
以2为根,45为左右节点,那么这样以来就出现了递归  
 
可知道可以递归,然后把这个递归代码写出来,也需要好好想想,关键是控制,递归什么  
时候停下来,这其实就是所有递归的最难的地方   
 
分析见代码:*/  

 
 //最关键的一步,通过前序和中序创建二叉树  
//pre1 是前序的最开始的点   pre2 是前序数组的结束下标点  in1,in2也一样,是中序的

void createTree(tree *&t,char q[],int pre1,int pre2,char w[],int in1,int in2)  
{  
      
    t=(tree*)malloc(sizeof(tree));   
    t->data=q[pre1]; //因为前序的第一个节点一定是根节点
    int i,k;  
    for(i=in1;i<=in2;i++)  
    {  
        if(q[pre1]==w[i])  
        {  
            k=i;break; //然后就是去中序中找下标
        }  
    }   
      
    if(k==in1) //当找到的下标和in1相同,举个例子,就是1 2345和425 1 3那么第二次也就是以425来构建右子树  
              //就是前序245 中序425,这个时候又是2为根节点,左书只有4,那么给4创建完空间后,直接让4的左子树为空
        t->lchild=NULL;  
    else   
        createTree(t->lchild,q,pre1+1,pre1+k-in1,w,in1,k-1); //控制每次分割出来的下标,例如,245,425,那么就是以这个为新的下标传进去递归
 
 
    if(k==in2)  
        t->rchild=NULL;  
    else   
        createTree(t->rchild,q,pre1+k-in1+1,pre2,w,k+1,in2);  
}   
 
main()   
{  
    tree *t;  
    char q[max],w[max];  
    int length;  
    createArray(q,w);   
    length=Length(q);  
    createTree(t,q,0,length-1,w,0,length-1);  
    show(t);  
}

例如输入:12453

                     42513

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值