PTA 7-23 还原二叉树

知识点:

  • 根据前序遍历和中序遍历还原二叉树

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

根据二叉树的性质,如果我们只给出二叉树的一种遍历方式的结果,不能完全确定一颗二叉树,这时的二叉树可能具有多种形态。但是当我们给出一颗二叉树的两种不同遍历方式的时候,就可以完全确定一颗二叉树。

这里以前序遍历和中序遍历为例。

假如我们给出两棵二叉树的前中序遍历分别为

前序遍历:ABDFGHIEC

中序遍历:FDHGIBEAC

  • 由前序遍历的性质,我们可以知道 A 一定是这棵树的根结点
  • 根据中序遍历可知, A 左边的一定是 A 的左子树,A 右边的一定是 A 的右子树
  • 同理,B 为 A 的左子树的根结点……
  • 如此递归下去就可以生成一颗确定的二叉树

由此,我们就可以写出递归的还原二叉树的代码:

#include <iostream>
#include <string>
using namespace std;

struct node {
    char data;
    node *left, *right;
    node(char _data): data(_data), left(NULL), right(NULL) {}
};

int n;  // 总结点数目
string preOrder, inOrder;

node *createTree(int preL, int preR, int inL, int inR) {
    if(preL > preR)
        return NULL;
    char nowChar = preOrder[preL];
    node *root = new node(nowChar);
    int pos = inOrder.find(nowChar);
    int len = pos - inL;    // 左子树的长度
    root->left = createTree(preL + 1, preL + len, inL, pos - 1);
    root->right = createTree(preL + len + 1, preR, pos + 1, inR);
    return root;
}

int getHeight(node *root) {
    if(root == NULL)
        return 0;
    else
        return max(getHeight(root->left), getHeight(root->right)) + 1;
}

int main()
{
    cin >> n >> preOrder >> inOrder;
    node *root = createTree(0, preOrder.size()-1, 0, inOrder.size() - 1);
    printf("%d", getHeight(root));
    return 0;
}

原文地址:https://www.cnblogs.com/veeupup/p/12631534.html

时间: 2024-08-29 22:20:41

PTA 7-23 还原二叉树的相关文章

SDUT 3343 数据结构实验之二叉树四:还原二叉树

数据结构实验之二叉树四:还原二叉树 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度. Input 输入数据有多组,每组数据第一行输入1个正整数N(1 <= N <= 50)为树中结点总数,随后2行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区分大小写)的字符串. Output 输出一个整数,即该二叉树的

通过先序遍历和中序遍历后的序列还原二叉树

当我们有一个 先序遍历序列:1,3,7,9,5,11 中序遍历序列:9,7,3,1,5,11 我们可以很轻松的用笔写出对应的二叉树.但是用代码又该如何实现? 下面我们来简单谈谈基本思想. 首先,先序遍历的顺序是根据 根-左孩子-右孩子 的顺序遍历的,那么我们可以率先确认的是先序遍历序列的第一个数就是根节点,然后中序遍历是根据 左孩子-根-右孩子 的顺序遍历的.我们通过先序遍历确认了根节点,那么我们只需要在中序遍历中找到根节点的位置,然后就可以很好地区分出,那些属于左子树的节点,那些是属于右子树的

SDUT 1489 求二叉树的先序遍历 (中序后序还原二叉树)

求二叉树的先序遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Description 已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历 Input 输入数据有多组,第一行是一个整数t (t<1000),代表有t组测试数据.每组包括两个长度小于50 的字符串,第一个字符串表示二叉树的中序遍历序列,第二个字符串表示二叉树的后序遍历序列. Output 输出二叉树的先序遍历序列 Exampl

UVA 548.Tree-fgets()函数读入字符串+二叉树(中序+后序遍历还原二叉树)+DFS or BFS(二叉树路径最小值并且相同路径值叶子节点权值最小)

Tree UVA - 548 题意就是多次读入两个序列,第一个是中序遍历的,第二个是后序遍历的.还原二叉树,然后从根节点走到叶子节点,找路径权值和最小的,如果有相同权值的就找叶子节点权值最小的. 最后输出来叶子节点. 一开始写的时候是用gets读入的,报CE, 要用fgets写,关于fgets(),传送门: fgets函数及其用法,C语言fgets函数详解 一开始用bfs过的,后来发现,好多人都是dfs过的,又写了一下dfs... 代码: 1 //二叉树的中序和后序遍历还原树并输出最短路径的叶子

根据二叉树的先序序列和中序序列还原二叉树并打印后序序列

#include<stdio.h> #include<stdlib.h> #include<iostream> using namespace std; struct Node { int value; Node *left; Node *right; Node(int value) { this->value = value; left = right = NULL; } }; bool bNotTree = false; Node* RebuildTree(i

根据先序、中序、后序遍历还原二叉树

遍历方式的转至二叉树的四种遍历方式 首先我们要知道三种遍历方式的规律: 先序遍历:跟在前,子树的根在后,左子树比右子树考前,且第一个就是根节点. 中序遍历:左子树在根左边,右子树在根右边,左边的部分是根节点的左子树的中序遍 历序列,右边部分是根节点右子树的中序遍历序列. 后序遍历:根在后,子树在根前且左子树比右子树靠前,且最后一个节点是根节点. 一.先序+中序 根据先序序列的第一个元素建立根节点 在中序序列中找到该元素,确定根节点的左右子树的中序序列 在先序序列中确定左右子树的先序序列 由左子树

还原二叉树

7-1 还原二叉树 (25 分) 给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度. 输入格式: 输入首先给出正整数N(≤50),为树中结点总数.下面两行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区别大小写)的字符串. 输出格式: 输出为一个整数,即该二叉树的高度. 输入样例: 9 ABDFGHIEC FDHGIBEAC 输出样例: 5 include<stdio.h> include<stdlib.h> define MAX 50 typed

根据二叉树的中序遍历和前序遍历,还原二叉树

现在有一个问题,已知二叉树的前序遍历和中序遍历:PreOrder:         GDAFEMHZInOrder:            ADEFGHMZ我们如何还原这颗二叉树,并求出他的后序遍历? 我们基于一个事实:中序遍历一定是 { 左子树中的节点集合 },root,{ 右子树中的节点集合 },前序遍历的作用就是找到每颗子树的root位置. 算法1输入:前序遍历,中序遍历1.寻找树的root,前序遍历的第一节点G就是root.2.观察前序遍历GDAFEMHZ,知道了G是root,剩下的节点

【LeetCode】106. Construct Binary Tree from Inorder and Postorder Traversal-通过中序和后续遍历还原二叉树

一.描述: 二.思路: 二叉树的中序遍历和前序遍历或和后续遍历能唯一确定一节课二叉树,即2中还原方式都需要中序遍历才能完成: 设二叉树的前序遍历序列为{1, 2, 4, 5, 3, 6},中序遍历序列为{4,2,5,1, 3, 6}:(红色标记表示以还原节点!!!) (1)-前序遍历的第一个节点是二叉树的根节点,{1, 2, 4, 5, 3, 6},对应中序中的位置是{4,2,5,1, 3, 6},所以中序序列中的 '1' 之前的全部元素为左子树元素,'1'之后的为右子树元素: (2)-左子树对