HDU 1710Binary Tree Traversals(已知前序中序,求后序的二叉树遍历)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1710

解题思路:可以由先序和中序的性质得到 : 先序的第一个借点肯定是当前子树的根结点, 那么在

中序中找到这个结点, 则这个结点左边的节点属于左子树, 右边的属于右子树。然后递归遍历就可以了。

样例:

9

1 2 4 7 3 5 8 9 6

4 7 2 1 8 5 9 3 6

7 4 2 8 9 5 6 3 1

如图:

因此,用深搜就能轻松解决了,注意DFS中的变量,以及向清楚DFS的条件,这题就简单多了,具体看代码吧:

#include<iostream>
#include<string.h>
#include<cstdio>
#include<stack>
using namespace std;
#define maxn 1001
int m,n,a[maxn],b[maxn];  //先序数组和后序数组
stack<int>Q;            //存放父节点
void dfs(int l1,int r1,int l2,int r2)
{//l1,r1,是先序遍历的数组的开始和末尾,l2,r2是中序遍历的数组的开始和末尾
    int i,j;
    Q.push(a[l1]);  //父节点入栈
    for(i=l2;i<=r2;i++)
        if(b[i]==a[l1])  break;
   //i 父节点在中序遍历的位置,j 左子树和右子树在先序遍历的分界点,即右子树的父节点
        j=l1+(i-l2+1);
        if(j<=r1&&i-1<=r2)     dfs(j,r1,i+1,r2);  //求解右子树
        if(l1+1<=j-1&&l2<=i-1)  dfs(l1+1,j-1,l2,i-1);  //求解左子树
//不能换位置,根据输出的后序遍历图可以看出,栈的后方为右半部分
}
int main()
{
    while(cin>>n)
    {
        for(int i=0;i<n;i++)  scanf("%d",&a[i]);
        for(int i=0;i<n;i++)  scanf("%d",&b[i]);
        dfs(0,n-1,0,n-1);
        while(!Q.empty())
        {
            printf("%d",Q.top());
            Q.pop();
            if(Q.size())  printf(" ");
        }
        cout<<endl;
    }
    return 0;
}
时间: 2024-08-27 10:09:27

HDU 1710Binary Tree Traversals(已知前序中序,求后序的二叉树遍历)的相关文章

HLG2040二叉树遍历已知前中,求后

二叉树的遍历 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 60(34 users) Total Accepted: 34(30 users) Rating: Special Judge: No Description 给出一棵二叉树的中序和前序遍历,输出它的后序遍历. Input 本题有多组数据,输入处理到文件结束. 每组数据的第一行包括一个整数n,表示这棵二叉树一共有n个节点. 接下来的一行每行包括n个整数,表示这棵树的中序遍

HDU 1710-Binary Tree Traversals(重建二叉树)

Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3340    Accepted Submission(s): 1500 Problem Description A binary tree is a finite set of vertices that is either empty or

已知前序中序求后序-二叉树

writer:pprp 思路很容易理解,但是实现还是有一点难度,容易错 参考书目:<算法竞赛宝典> 代码如下: //已知前序中序,求后序 #include <iostream> using namespace std; //a是前序,b是中序 void hwg(string a,string b) { int ll,lr; for(unsigned int i = 0; i < b.length(); i++) { if(a[0] == b[i]) //找到根节点 { ll

PAT A1086 Tree Traversals Again [二叉树前序中序求后序]

题目描述 链接 用栈的形式给出一棵二叉树的建立的顺序,求这棵二叉树的后序遍历 分析 性质:树的先序等于入栈次序,树的中序遍历等于出栈次序 先序:先访问根再入栈,所以入栈次序就是先序遍历次序 中序:先递归访问左子树,回溯时访问根,回溯时即出栈时,所以出栈次序就是中序遍历 所以问题转换为已知先序中序,求后序 已知先序中序求后序的方法 \(root\) 保存先序中根的位置,\(st\),\(ed\) 为中序子树的起始结束位置 遍历中序,找到中序根的位置\(i\),从而分成左右子树 左子树在先序中根的位

HDU 1710 二叉树遍历,输入前、中序求后序

1.HDU  1710  Binary Tree Traversals 2.链接:http://acm.hust.edu.cn/vjudge/problem/33792 3.总结:记录下根结点,再拆分左右子树,一直搜下去.感觉像dfs. 题意:二叉树,输入前.中序求后序. (1)建立出一颗二叉树,更直观.但那些指针用法并不是很懂. #include<iostream> #include<cstdio> #include<cstdlib> using namespace

HDU 1710-Binary Tree Traversals(二进制重建)

Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3340    Accepted Submission(s): 1500 Problem Description A binary tree is a finite set of vertices that is either empty or

关于二叉树的问题1-已知前序,中序求后序遍历

对于一棵二叉树而言,可以由其前序和中序或者中序和后序的遍历序列,确定一棵二叉树. 那么对于已知前序和中序序列,求后序序列也就是先还原二叉树,然后对其进行后序遍历即可. 二叉树结点的结构定义如下: struct TreeNode { char value; TreeNode *leftChild; TreeNode *rightChild; }; 实现代码如下: #include <stdio.h> #include <string.h> #include <stdlib.h&

二叉树--已知先序中序求后序--已知中序后序求先序(基本按照网上某大神思路搬过来的)

思路来自(转载自)  http://www.cnblogs.com/fzhe/archive/2013/01/07/2849040.html 题目描述不说了. 前序遍历:  GDAFEMHZ 中序遍历:  ADEFGHMZ 求中序遍历. 1 确定根,确定左子树,确定右子树. 2 在左子树中递归. 3 在右子树中递归. 4 打印当前根. 代码如下: 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 char pr[1000],in[100

UVA 536 Tree Recovery(由前序中序求后序,经典)

Tree Recovery Time Limit: 3000 MS Little Valentine liked playing with binary trees very much. Her favorite game was constructing randomly looking binary trees with capital letters in the nodes. This is an example of one of her creations: D / / B E /