ural 1136. Parliament
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1136
题目描述:给定一个按照(左子树-右子树-根)(即先序)遍历序列的树,求其按照 右子树-左子树-根 遍历的结果。(每个数都不同)
题目思路:按照题目意思其实构造的是一个二叉查找树,满足左子树元素都不大于当前根的元素,右子树元素都不小于当前根的元素。
而且二叉查找树按照 中序遍历 的结果是元素按照递增顺序输出(二叉查找树的性质)。所以实际上又告诉了你中序遍历的结果(即把所给元素递增排序的结果)。
所以只要按照它给的后序遍历和隐含的中序遍历的序列,递归构造并输出就可以了。
如果不熟悉二叉树,这是几篇不错的教程:
http://blog.csdn.net/hinyunsin/article/details/6315502(评论指出了原文中的错误)
http://blog.csdn.net/pegasuswang_/article/details/10169397
http://www.slyar.com/blog/c-preord-inord-tree.html这个版本的代码比较容易理解
本题代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
const int M = 3010;
int postord[M], inord[M]; //后序和中序遍历序列
void build(int n, int *postord, int *inord)
{
if (n <= 0)
return;
int p = std::find(inord, inord + n, postord[n-1]) - inord; //计算根节点在中序遍历中的位置
build(n - p - 1, postord + p, inord + p + 1); //递归构造右子树的(右-左-根)遍历
build(p, postord, inord); //递归构造左子树的(右-左-根)遍历
printf("%d ", postord[n-1]); //输出根节点
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i)
{
scanf("%d", postord + i);
inord[i] = postord[i];
}
std::sort(inord, inord + n);
build(n, postord, inord);
return 0;
}
几点说明:如果不理解代码,就找简单数据在纸上试试。要不看代码是不容易理解的。
这一题我直接在构造的时候就输出了,比较简练。
int p = std::find(inord, inord + n, postord[n-1]) - inord; //计算根节点在中序遍历中的位置
build(n - p - 1, postord + p, inord + p + 1); //递归构造右子树的遍历
build(p, postord, inord); //递归构造左子树的遍历
printf("%d ", postord[n-1]); //输出根节点
这几句是关键代码:
build(n - p - 1, postord + p, inord + p + 1); //递归构造右子树的遍历
参数n-p-1是 右 子树的结点个数,用来控制递归深度:post+p是新的 右子树 在 后序遍历 中的位置;inord+p+1是新的 右子树 在 中序遍历 中的位置。
build(p, postord, inord); //递归构造左子树的遍历
参数n-p-1是 左 子树的结点个数,用来控制递归深度:post+p是新的 左子树 在 后序遍历 中的位置;inord+p+1是新的 左子树 在 中序遍历 中的位置。
最后输出根节点就行了。
调整三句的位置就可以实现任意六种遍历的次序。
当然也可以先构造,再输出,不过麻烦点。
代码来自/*gaoshangbo*/
//给定后序遍历和中序遍历,求先遍历右子树, 左子树, 根的序列
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
int s[3005], t[3005];
typedef struct node
{
int data;
node *l;
node *r;
}node;
node *Creat(int *s,int *t,int n)
{
int *p;
node *q;
int k;
if(n<=0) return NULL;
q=new node;
q->data=*s;
for(p=t;p<t+n;p++)
if(*p==*s) break;
k=p-t;
q->l=Creat(s-n+k,t,k);
q->r=Creat(s-1,t+k+1,n-k-1);
return q;
}
void print(node *root)
{
if(root==NULL) return ;
print(root->r);
print(root->l);
printf("%d ",root->data);
}
int main()
{
node *root;
int n, i;
scanf("%d", &n);
for(i = 0; i < n; i ++)
{
scanf("%d", &s[i]);
t[i] = s[i];
}
sort(t, t+n);
root = Creat(s+n-1,t,n);
print(root);
printf("\n");
return 0;
}
ural 1136. Parliament的更多相关文章
- URAL 1136 Parliament 二叉树水题 BST后序遍历建树
二叉树水题,特别是昨天刚做完二叉树用中序后序建树,现在来做这个很快的. 跟昨天那题差不多,BST后序遍历的特型,找到最后那个数就是根,向前找,比它小的那块就是他的左儿子,比它大的那块就是右儿子,然后递 ...
- URAL 1136 Parliament (DFS)
题意 输入一棵树的后缀表达式(按左-右-中顺序访问),这棵树的每一个结点的数值都比它的左子树结点的数值大,而比它的右子树结点的数值小,要求输出其按右-左-中顺序访问的表达式.所有的数都为正整数,而且不 ...
- timus 1136 Parliament(二叉树)
Parliament Time limit: 1.0 secondMemory limit: 64 MB A new parliament is elected in the state of MMM ...
- timus 1136 Parliament(e)
Parliament Time limit: 1.0 secondMemory limit: 64 MB A new parliament is elected in the state of MMM ...
- 1136. Parliament(二叉树)
1136 先由后左 再父 建一个二叉树 #include <iostream> #include<cstdio> #include<cstring> #includ ...
- ural 1073. Square Country
1073. Square Country Time limit: 1.0 secondMemory limit: 64 MB There live square people in a square ...
- 后缀数组 POJ 3974 Palindrome && URAL 1297 Palindrome
题目链接 题意:求给定的字符串的最长回文子串 分析:做法是构造一个新的字符串是原字符串+反转后的原字符串(这样方便求两边回文的后缀的最长前缀),即newS = S + '$' + revS,枚举回文串 ...
- ural 2071. Juice Cocktails
2071. Juice Cocktails Time limit: 1.0 secondMemory limit: 64 MB Once n Denchiks come to the bar and ...
- ural 2073. Log Files
2073. Log Files Time limit: 1.0 secondMemory limit: 64 MB Nikolay has decided to become the best pro ...
随机推荐
- 菜鸟学开店—自带U盘的打印机
本文旨在提供最简单.便宜.有效的解决方案,解决普通用户最困扰的问题.今天提供普通用户一个低价的小票打印机驱动安装解决方案 相信很多用户都碰到过这种情况,电脑的重装了系统,打印机的驱动没有备份,要用打印 ...
- Jquery不生效
$(document).ready(function(){这个都没有生效, 1.网上查了说是jquery的路劲引入的有问题,经查并不是这个问题 2.换了一个jquery的版本,发现生效了. 原不生效文 ...
- iOS如何准确获取通知
iOS获取通知需要注意以下三个地方iOS 设备收到一条推送(APNs),用户点击推送通知打开应用时,应用程序根据状态不同进行处理需在 AppDelegate 中的以下两个方法中添加代码以获取apn内容 ...
- C#读取Visual FoxPro(*.dbf)数据并使用SqlBulkCopy插入到SqlServer 2008 R2数据表中
公司数据库从32位的SqlServer 2005升级到64位的SqlServer 2008 R2后,无法再像原来通过Link Server连接VFP同步数据,因此考虑用代码程序从VFP数据库中读取所需 ...
- WPF 自定义Button控件及样式
这次通过最近做的小例子说明一下自定义Button控件和样式. 实现的效果为:
- java问题整理
1.一个“.java”源文件中是否可以包括多个类(不是内部类)?有什么限制? 答:可以有多个类.但只能有一个public类.并且public类名必须与文件名相一致. 2.Java有没有goto? ...
- java操作excel常用的两种方式
Excel是我们平时工作中比较常用的用于存储二维表数据的,JAVA也可以直接对Excel进行操作,在这篇博客中将为大家介绍两种操作Excel的方式,分别为:jxl和poi. 对于两者的区别网上有测试如 ...
- Ubuntu 12.04 下安装配置 JDK 7(tar)
第一步:下载jdk-7u45-linux-i586.tar.gz 到Orcale的JDK官网下载JDK7的tar包 第二步:解压安装 tar -zxvf ./jdk-7u45-linux-i586.t ...
- javascript获取div高度
DOM的: 获得了div的高度值 = document.getElementById("目标id").offsetHeight;
- 【Linux】常用命令
一.文件结构 /: 根目录 /bin: 系统所需要的那些命令位于此目录. /boot: Linux的内核及引导系统程序所需要的文件目录,GRUB或LILO系统引导管理器也 ...