acmsdut 3343 数据结构实验之二叉树四:(先序中序)还原二叉树

在这里插入图片描述
知识点:
1.由前序遍历+中序遍历||后序遍历+中序遍历可以得到一个完整的二叉树,由前序+后序遍历无法确定一个二叉树。
2.前序和后序遍历可以确定根(前序遍历第一个为根,后序遍历最后一个为根),此性质与遍历顺序有关,因为前序遍历是“根左右”,后序遍历是“左右根”。
3.中序遍历的特征:如果已知根节点,那么在中序遍历的结果中,排在根结点左边的点都在左子树上,排在根节点右边的都在右子树上。

已知上述条件,可以通过中序和前序遍历结果得到整颗二叉树,可以通过递归的方法。思路为把每颗子树的子根看着一个根节点,先左后右得递归,递归边界为没有左儿子时。

给出代码:

#include <stdio.h>
#include <stdlib.h>
typedef struct Node //定义节点,用typedef较为方便
{
    int data;
    struct Node *l,*r;
}node;
node *creat(int n,char *qian,char *zhong)//建立二叉树
{
    int i;
    node *root;//定义根节点
    if(n==0)//递归边界
    {
        return NULL;
    }
    root=(node*)malloc(sizeof(node));//给根结点开空间
    root->data=qian[0];//将前序遍历结果的最前面的值赋给根节点(因为前序遍历结果的首个一定为树的根)
    for(i=0;i<n;i++)//在中序遍历中找到根节点所在的位置,即<i的部分为左子树,>i的部分为右子树
    {
        if(qian[0]==zhong[i]) break;
    }
    //接下来是分别递归左右子树,遵循先左后由的原则
    root->l=creat(i,qian+1,zhong);//由于前序遍历的第一个已经放入树中了,所以+1更新前序数组,且只在中序遍历结果中查找<i部分的值,递归思想,我也不太讲的清,推荐自己模拟感受一下
    root->r=creat(n-1-i,qian+1+i,zhong+1+i);//右子树递归
    return root;
}
int imax(int a,int b)//自定义比大小函数
{
    if(a>=b) return a;
    else return b;
}
int deep(node *root)//计算二叉树深度,也用递归
{
    int hl,hr,max;
    if(root!=NULL)
    {
    	//分别递归左右子树的深度
        hl=deep(root->l);
        hr=deep(root->r);
        max=imax(hl,hr);//比较左右子树的大小,取较大的
        return max+1;//返回上层递归,所以层数+1,这里要思考一下,计算深度是从下往上的,而不是从上往下,从递归边界也可以看出。
    }
    else//递归边界
    {
        return 0;
    }
}
int main()
{
    char qian[51],zhong[51],n,h;
    while(~scanf("%d",&n))
    {
        scanf("%s %s",qian,zhong);
        node *root;
        root=creat(n,qian,zhong);
        h=deep(root);
        printf("%d\n",h);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值