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;

}

 

 

 

你可能感兴趣的:(li)