PTA搜索树判断

4-2-二叉搜索树 搜索树判断 (25分)

对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。如果我们交换每个节点的左子树和右子树,得到的树叫做镜像二叉搜索树。

现在我们给出一个整数键值序列,请编写程序判断该序列是否为某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,如果是,则输出对应二叉树的后序遍历序列。

输入格式:
输入的第一行包含一个正整数N(≤1000),第二行包含N个整数,为给出的整数键值序列,数字间以空格分隔。

输出格式:
输出的第一行首先给出判断结果,如果输入的序列是某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,则输出YES,否侧输出NO。如果判断结果是YES,下一行输出对应二叉树的后序遍历序列。数字间以空格分隔,但行尾不能有多余的空格。

输入样例1:

7
8 6 5 7 10 8 11

输出样例1:

YES
5 7 6 8 11 10 8

输入样例2:

7
8 6 8 5 10 9 11

输出样例2:

NO

主要思路是
1.生成二叉搜索树(用某二叉搜索树的前序遍历建成的搜索树的前序遍历一定相等,故可用此来判断是否属于某搜索树的前序遍历)(之前一直在纠结不同序列但相同数字建成的搜索树不一定相同)
2.判断该搜索树的前序遍历是否和所给的一样

#include<stdio.h>
#include<stdlib.h>
#define max 10000
int a[max], b[max],c[max];
int t;//全局变量还挺好用的
typedef struct node* Tree;
struct node {
	int data;
	Tree Left;
	Tree Right;
};
Tree Insert(Tree T, int x)
{
	if (T == NULL) {        //递归出口,在递归程序我觉得这个其实是最难想到的
		T= (Tree)malloc(sizeof(struct node));
		T->data = x;
		T->Left = T->Right = NULL;
	}
	else {
		if (x <T->data) {
			T->Left = Insert(T->Left, x);
		}
		else {
			T->Right = Insert(T->Right, x);
		}
	}
	return T;
}
Tree swap(Tree T)
{
	if (T) {  //如果用T->Left&&T->Right,那么当一个空一个不空就会出现段错误,从下层开始交换
		T->Left = swap(T->Left);
		T->Right = swap(T->Right);
		Tree tmp;
		tmp = T->Left;
		T->Left = T->Right;
		T->Right = tmp;
	}
	return T;
}
void pre(Tree T)// 先序遍历
{
	if (T) {
		b[t++] = T->data;
		pre(T->Left);
		pre(T->Right);
	}
}
void post(Tree T)
{
	if (T) {
		post(T->Left);
		post(T->Right);
		c[t++] = T->data;
	}
}
int main()
{
	int n,flag=0,i;
	Tree T = NULL,T1;
	scanf("%d", &n);
	for (int k = 0; k < n; k++) {
		scanf("%d", &a[k]);
		T=Insert(T, a[k]);
	}
	if (n == 1) {
		printf("YES\n%d", a[0]);
		return 0;
	}
	t = 0;//每次调用pre或者post要进行初始化
	pre(T);//b
	for (i = 0; i < n; i++) {
		if (a[i] != b[i]) {
			flag++;
			break;
		}
	}
	if (flag == 0) {
		t = 0;
		post(T);
		printf("YES\n");
		for (i = 0; i < n; i++) {
			if (i == 0)printf("%d", c[i]);
			else printf(" %d", c[i]);
		}
	}
	else {
		t = 0;
		T1=swap(T);
		pre(T1);
		for (i = 0; i < n; i++) {
			if (a[i] != b[i]) {
				flag++;
				break;
			}
		}
		if (flag == 1) {
			t = 0;
			post(T);
			printf("YES\n");
			for (i = 0; i < n; i++) {
				if (i == 0)printf("%d", c[i]);
				else printf(" %d", c[i]);
			}
		}
		else
			printf("NO");
	}
	return 0;
}

附:不同序列但相同数字建成的搜索树不一定相同

Description
判断两序列是否为同一二叉搜索树序列

Input
开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。

Output
如果序列相同则输出YES,否则输出NO

Sample Input
6

45021

12045

54120

45021

45012

21054

50412

0

Sample Output
NO

NO

YES

NO

NO

NO

HINT
Source

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值