浙大版《数据结构(第2版)》题目集-练习4.1 根据后序和中序遍历输出先序遍历 (25分)

本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。

输入格式:

第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。

输出格式:

在一行中输出Preorder:以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。

输入样例:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

输出样例:

Preorder: 4 1 3 2 6 5 7

参考代码:

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

int a[30],b[30];//数组a存储后序遍历序列,数组b存储中序遍历序列

typedef struct treeNode *binTree;
struct treeNode{
    int data;
    binTree left;
    binTree right;
};

void preorderTraversal(binTree BT);    //先序遍历
binTree buildTree(int start,int end,int root);//建立二叉树

int main()
{
    int n;
    scanf("%d",&n);
    int i;
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(i=0;i<n;i++)
    {
        scanf("%d",&b[i]);
    }
    printf("Preorder:");
    binTree head=buildTree(0,n-1,n-1);
    preorderTraversal(head);
    return 0;
}

void preorderTraversal(binTree BT)
{
    if(BT)
    {
        printf(" %d",BT->data);
        preorderTraversal(BT->left);
        preorderTraversal(BT->right);
    }
}

//start,end表示在中序遍历数组b中一棵树的起始位置和终止位置
//root表示在后序遍历数组a中根的位置
binTree buildTree(int start,int end,int root)
{
    binTree bt=(binTree)malloc(sizeof(struct treeNode));
    bt->data=a[root];
    bt->left=NULL;
    bt->right=NULL;
    int i;
    for(i=start;i<=end;i++)//遍历中序遍历序列的数组
    {
        if(a[root]==b[i])  //在中序遍历序列数组b中找到数的根
        {
            if(i!=start)//有左子树
            {
                bt->left=buildTree(start,i-1,root-(end-i)-1);
            }
            if(i!=end)  //有右子树
            {
                bt->right=buildTree(i+1,end,root-1);
            }
            break;
        }
    }
    return bt;
}

思路:

首先通过后序遍历序列和中序遍历序列建立一棵二叉树,再对二叉树进行前序遍历。
对二叉树进行前序遍历比较简单,采用递归或非递归算法均可(本题采用的是递归算法),这题主要是如何通过后序遍历和中序遍历建立一棵二叉数。
在这里插入图片描述

我们从图中可以看到后序遍历可以很容易的找到根节点是哪个数(后序遍历序列中一棵树的结尾位置),再通过遍历中序遍历序列找到中序遍历序列根节点的位置,可以找到左子树和右子树有哪些,再通过后序遍历确定左右子树的根节点,通过递归建立一棵完整的二叉树。
如何在后序遍历中确定左右子树根节点的位置?
左子树根节点位置root-(end-i)-1,树的根节点位置-右子树长度-1;
右子树根节点位置root-1,树的根节点位置-1。
总的来说:
后序遍历:确定一棵树的根节点是哪个;
中序遍历:确定一棵树的左右子树有哪些。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅帅帅的阿豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值