1009 比较两个二叉排序树是否相同

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

样例输入:

2

567432    
543267
576342
0

样例输出:

YES

NO

算法实现一:

/*判断两个二叉排序树是否相同  */
//建树 根据前序和中序遍历序列是否相同进行判断
//由中序序列和前序或者后序序列能唯一的确定一棵树
//wa
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct BiTree{
	int data;
	struct BiTree * lchild;//
	struct BiTree * rchild;
}BiTree;
//技巧
char str1[25],str2[25];//前序和中序序列保存于同一数组中便于比较
int size1,size2;//两个数组的大小
char *str;//方便子函数的编写
int *size;// 指示当前的操作的字符串数组

BiTree *Insert(BiTree *p,int x){//构建二叉排序树
	if(p==NULL){
		p=(BiTree *)malloc(sizeof(BiTree));
		p->data=x;
		p->lchild=p->rchild=NULL;
		return p;
	}
	else if(x<p->data)
		p->lchild=Insert(p->lchild,x);
	else if(x>p->data)
		p->rchild=Insert(p->rchild,x);
	return p;
}

void PreOrder(BiTree *p){//前序遍历
	if(p!=NULL){
		str[(*size)++]=p->data+'0';
		PreOrder(p->lchild);
		PreOrder(p->rchild);
	}
}

void InOrder(BiTree *p){//中序遍历
	if(p!=NULL){	
		InOrder(p->lchild);
		str[(*size)++]=p->data+'0';
		InOrder(p->rchild);
	}
}


int main(){
	int n,i;
	char src[10];
	freopen("test.txt","r",stdin);
	while(scanf("%d",&n)!=EOF){
		if(n==0) break;
		scanf("%s",src);
		BiTree *tree=NULL;
		
		for(i=0;src[i]!=0;i++){
			tree=Insert(tree,src[i]-'0');
		}
		
		size1=0;
		str=str1;
		size=&size1;
		PreOrder(tree);
		InOrder(tree);
		str1[size1]=0;//!!!
	
		for(i=0;i<n;i++){
			BiTree *p=NULL;
			int j;
			scanf("%s",src);
			for(j=0;src[j]!=0;j++){
				p=Insert(p,src[j]-'0');
			}
			size2=0;
			str=str2;
			size=&size2;
			PreOrder(p);
			InOrder(p);
			str2[size2]=0;
				
			printf("%s\n",strcmp(str1,str2)==0 ?"Yes":"NO");
		}
	}
	fclose(stdin);
	return 0;
}





		
	
特别注意:

1.指针变量定义时就要初始化为空,字符串数组输出前要在结尾加上字符串结束符;

2.这是本题的基本思路,基础的数据结构要掌握牢固!

算法实现二:

/* 判断两个二叉排序树是否相同 */
//用静态数组模拟二叉排序树的建立过程
void creat(char a[],int x[]){//模拟二叉排序树的插入过程
	int i,j,temp;
	for(i=0;a[i]!=0;i++){
		temp=a[i]-'0';
		for(j=1;j<1024;){
			if(x[j]==-1){
				x[j]=temp;
				break;
			}
			else if(temp>x[j]){
				j=2*j+1;
			}
			else{
				j=2*j;
			}
		}
	}
}
#include<stdio.h>

int main(){
	int n,i,j,bb[1024],cc[1024];//静态数组;
	char a[10];
	freopen("test.txt","r",stdin);
	while(scanf("%d",&n)!=EOF){
		scanf("%s",a);
		for(i=1;i<1024;i++){//数组元素均初始化为-1
			bb[i]=-1;
		}
		creat(a,bb);//建立被比较字符串的二叉排序树
		for(j=0;j<n;j++){//n次比较 注意ij指针的使用 容易乱
			scanf("%s",a);
			for(i=1;i<1024;i++){	
				cc[i]=-1;
			}
			creat(a,cc);
			for(i=0;i<1024;i++){
				if(bb[i]!=cc[i])
					break;
			}
			if(i==1024)
				printf("YES\n");
			else
				printf("NO\n");
		}
	}
	fclose(stdin);
	return 0;
}
			

		
特别注意:

1.这是借鉴别人的算法思想,根据二叉排序树的性质,采用静态数组来模拟二叉树排序的建立过程,数组下标代表了满二叉树时的对应结点;

2.数组为什么要用1024大小?题目中说明字符串即结点个数不大于10,即在极端情况下,树的深度为10 ,那么树的最大结点应为1024;

3.遇到这类题目时,在没有更好的办法时再建树,建树一定是没有更好的算法的下下之策。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值