二叉树的遍历--由俩个不同的遍历复原二叉树

二叉树的遍历

在最近期间做到一系列相似的题:
 # 给了树的前序遍历或者后续遍历加上中序遍历,要求复原二叉树。
 #在陈越的数据结构那门课中我们知道只有前序和后序遍历结果知道是无法复原二叉树的

上例题:

1.给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。

输入格式:
输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。

输出格式:
在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例:

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

输出样例:

4 1 6 3 5 7 2

该题是要求直接输出该树的层序遍历,主要思路就是将该树复原再输出

代码:

#include<stdio.h>
#include<malloc.h>
#include<iostream>
struct TNode {
    int data;
    struct TNode* left, * right;
};
typedef struct TNode* Tree;
int post[30], mid[30];//存中序和后序的数字,全局变量可以在递归函数里面用
Tree creattree(int root, int start, int end);//将俩个数组变成一颗树
void show(Tree t);//将数用层序遍历显示出来
int main()
{
    int n;
    scanf("%d", &n);
    int i = 0;
    for (i = 0; i < n; i++) {
        scanf("%d", &post[i]);
    }
    for (i = 0; i < n; i++) {
        scanf("%d", &mid[i]);
    }
    Tree t;
    t = creattree(n - 1, 0, n - 1);
    show(t);
    return 0;
}
Tree creattree(int root, int start, int end)
{
    Tree t;
    if (start > end) {//判断递归结束的标志
        return NULL;
    }
    int i = 0;
    for (i = start; post[root] != mid[i]; i++);//寻找节点
    t = (Tree)malloc(sizeof(struct TNode));
    t->data = post[root];
    t->left = creattree(root - (end - i) - 1, start, i - 1);//递归左侧填充树
    t->right = creattree(root - 1, i + 1, end);//递归填充右侧树
    return t;
}
void show(Tree t)//层序遍历
{
    if (t == NULL) {
        exit(0);
    }
    int flag = 0;
    Tree q[30];//做一个队列
    int front = -1, real = 0;
    q[real] = t;
    while (real != front) {//判断队列是否结束
        front++;
        if (flag++) {//避免第一个输出空格
            printf(" ");
        }
        printf("%d", q[front]->data);
        if (q[front]->left != NULL) {
            q[++real] = q[front]->left;//将树的链式结构变成队列的数组结构
        }
        if (q[front]->right != NULL) {
            q[++real] = q[front]->right;
        }
    }
}

以上是第一题的解法,后序加中序。

2.给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。

输入格式:
输入首先给出正整数N(≤50),为树中结点总数。下面两行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区别大小写)的字符串。

输出格式:
输出为一个整数,即该二叉树的高度。

输入样例:

9
ABDFGHIEC
FDHGIBEAC

输出样例:

5

该题要求输出树的高度,那么先复原树再求高度。
代码:

#include<stdio.h>
#include<malloc.h>
struct TNode {
    char data;
    struct TNode* Left, * Right;
};
typedef struct TNode* Tree;
Tree creattree(int root, int star, int end);
int hight(Tree t);
char pre[50], ino[50];
int main()
{
    int n;
    scanf("%d\n", &n);
    int i = 0;
    for (i = 0; i < n; i++) {
        scanf("%c", &pre[i]);
    }
    getchar();
    for (i = 0; i < n; i++) {
        scanf("%c", &ino[i]);
    }
    Tree t;
    t = creattree(0, 0, n - 1);
    int zb;
    zb = hight(t);
    printf("%d", zb);
}
Tree creattree(int root, int star, int end)
{
    if (star > end) {
        return NULL;
    }
    int i = 0;
    Tree t;
    for (i = star; pre[root] != ino[i]; i++);
    t = (Tree)malloc(sizeof(struct TNode));
    t->data = pre[root];
    t->Left = creattree(root + 1,star,i - 1);
    t->Right = creattree(root-star+i + 1, i + 1, end);
    return t;
}
int hight(Tree t)
{
    int lmax, left, right;
    if (t) {
        left = hight(t->Left);
        right = hight(t->Right);
        lmax = (left > right) ? left : right;
        return lmax + 1;
    }
    return 0;
}

该题目是给了前序和中序的类型。

总结:

这俩题的解法主要的差别是在复原树的方法上

前序加中序的:
Tree creattree(int root, int star, int end)
{
    if (star > end) {
        return NULL;
    }
    int i = 0;
    Tree t;
    for (i = star; pre[root] != ino[i]; i++);
    t = (Tree)malloc(sizeof(struct TNode));
    t->data = pre[root];
    t->Left = creattree(root + 1, star, i - 1);
    t->Right = creattree(root - star + i + 1, i + 1, end);
    return t;
}
后序加中序的:
Tree creattree(int root, int start, int end)
{
    Tree t;
    if (start > end) {
        return NULL;
    }
    int i = 0;
    for (i = start; post[root] != mid[i]; i++);//寻找节点
    t = (Tree)malloc(sizeof(struct TNode));
    t->data = post[root];
    t->left = creattree(root - (end - i) - 1, start, i - 1);//递归左侧填充树
    t->right = creattree(root - 1, i + 1, end);//递归填充右侧树
    return t;
}

二者手法有些相似,但是在函数递归的时候要有所区别

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值