2021/05/25 7-4 是否同一棵二叉搜索树 (25 分)

给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。

输入格式:

输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后L行,每行给出N个插入的元素,属于L个需要检查的序列。

简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理。

输出格式:

对每一组需要检查的序列,如果其生成的二叉搜索树跟对应的初始序列生成的一样,输出“Yes”,否则输出“No”。

输入样例:

4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0

输出样例:

Yes
No
No

本题思路:创建出两个二叉搜索树,采用先序遍历进行两颗树的比较,有不同的直接输出No即可;

#include<stdio.h>
#include<stdlib.h>
int Flag;//全局变量flag  
typedef struct tree{
	int date;
	struct tree *left,*right;
}Bintree;
Bintree *insert(Bintree *bt,int x);//插入函数 
void printS(Bintree *t1,Bintree *t2);//先序遍历并且进行比较 
int main()
{
	int n,l,i,x;	
	while(scanf("%d",&n)&&n!=0)
	{
	    scanf("%d",&l);	
		Bintree *bt1;	
		bt1=NULL;
		for(i=0;i<n;i++)
		{
			scanf("%d",&x);	
			bt1=insert(bt1,x);
		}					
		while(l--)
		{
			Bintree *bt2;
            bt2=NULL;
              for(i=0;i<n;i++)
		    { 
			   scanf("%d",&x);
			   bt2=insert(bt2,x);
		    } 
            Flag=1;
		    printS(bt1,bt2);
		    (Flag)?printf("Yes\n"):printf("No\n");	                       
		}			
	}
	return 0;
}
Bintree *insert(Bintree *bt,int x)
{		
	if(bt==NULL)
	{
		bt=(Bintree*)malloc(sizeof(Bintree));
		bt->date=x;
		bt->left=NULL;
		bt->right=NULL;	
		return bt;			
	}
	if(bt!=NULL)
	{
		if(x<(bt->date))  //二叉搜索树的特性,比它小放它左边,反之放右边 
		bt->left=insert(bt->left,x);
		else
		bt->right=insert(bt->right,x);
	}
	return bt;
}
void printS(Bintree *t1,Bintree *t2)
{
	if(t1&&t2)
	{
		if(t1->date!=t2->date)//如果有出现不同 直接将全局变量变为0 
			Flag=0;
		else  //否则递归的遍历 
		{
		printS(t1->left,t2->left);
		printS(t1->right,t2->right);	
		}
	}
}

 

测试点提示结果分数耗时内存
0sample 换顺序。有Yes,有No:根不同,子树根不同。树有单边、有双子树

答案正确

124 ms184 KB
1最大N,多组合

答案正确

84 ms336 KB
2N=1,只有1个节点

答案正确

34 ms276 KB
3卡只判断数字相对先后位置的错误算法

答案正确

23 ms196 KB
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
9.25实现下列函数: int Search(SSTable s, KeyType k); /* Index the element which key is k */ /* in StaticSearchTable s. */ /* Return 0 if x is not found. */ 静态查找表的类型SSTable定义如下: typedef struct { KeyType key; ... ... // 其他数据域 } ElemType; typedef struct { ElemType *elem; int length; } SSTable; int Search(SSTable a, KeyType k) /* Index the element which key is k */ /* in StaticSearchTable s. */ /* Return 0 if x is not found. */ { int i; if(a.length==0) return ERROR; //先判断a是否为空 a.elem[a.length+1].key=k; for(i=1;a.elem[i].key>k;i++) if(i>=a.length||a.elem[i].key<k) //不能忽略i=a.length这种情况 return ERROR; return i; } /* { int i; a.elem[a.length+1].key=k; for(i=1;a.elem[i].key>k;i++) if(i>a.length||a.elem[i].key<k) return ERROR; return i; } */ 9.26② 试将折半查找算法改写成递归算法。 实现下列函数: int BinSearch(SSTable s, int low, int high, KeyType k); /* Index the element which key is k */ /* in StaticSearchTable s. */ /* Return 0 if x is not found. */ 静态查找表的类型SSTable定义如下: typedef struct { KeyType key; ... ... // 其他数据域 } ElemType; typedef struct { ElemType *elem; int length; } SSTable; int BinSearch(SSTable s, int low, int high, KeyType k) /* Index the element which key is k */ /* in StaticSearchTable s. */ /* Return 0 if x is not found. */ { int mid; if(low<=high) { mid=(low+high)/2; if(s.elem[mid].key==k) return mid; if(s.elem[mid].key<k) return BinSearch(s,mid+1,high,k); if(s.elem[mid].key>k) return BinSearch(s,low,high-1,k); } return 0; } /* { int mid; if(low<=high) { mid=(low+high)/2; if(s.elem[mid].key<k) return BinSearch(s,mid+1,high,k); else return BinSearch(s,low,high-1,k); } return 0; } */ 9.31④ 试写一个判别给定二叉树是否为二叉排序树的算法,设此二叉树以二叉链表作存储结构。且树中结点的关键字均不同。 实现下列函数: Status IsBSTree(BiTree t); /* 判别给定二叉树t是否为二叉排序树。*/ /* 若是,则返回TRUE,否则FALSE */ 二叉树的类型BiTree定义如下: typedef struct { KeyType key; ... ... // 其他数据域 } ElemType; typedef struct BiTNode { ElemType data; BiTNode *lchild,*rchild; }BiTNode, *BiTree; KeyType predt=-32767; Status IsBSTree(BiTree t) /* 判别给定二叉树t是否为二叉排序树。*/ /* 若是,则返回TRUE,否则FALSE */ { if( t )//&& ! ( t->lchild || t->rchild ) )//空树和叶不用判断 { if( t->lchild && ( t->data.key < t->lchild->data.key ) )//左孩不空,左孩的key比本身的大 return FALSE; else if( t->rchild && ( t->data.key > t->rchild->data.key ) )//右孩不空,右孩的key比本身的大 return FALSE; else if( !IsBSTree( t->lchild ) )//判断左子树 return FALSE; else if( !IsBSTree( t->rchild ) )//判断右子树 return FALSE; } return TRUE; } /* { if(!t) return OK; if(t&&!t->lchild&&!t->rchild) return OK; else { if(t->lchild->data.key<t->data.key) IsBSTree(t->lchild); if(t->lchild->data.key>=t->data.key) return ERROR; if(t->rchild->data.key>t->data.key) IsBSTree(t->rchild); else return ERROR; return OK; } } */ 9.33③ 编写递归算法,从大到小输出给定二叉排序树中所有关键字不小于x的数据元素。要求你的算法的时间复杂度为O(log2n+m),其中n为排序树中所含结点数,m为输出的关键字个数。 实现下列函数: void OrderOut(BiTree t, KeyType x, void(*visit)(TElemType)); /* Output is to use visit(t->data); */ 二叉树的类型BiTree定义如下: typedef struct { KeyType key; ... ... // 其他数据域 } ElemType; typedef struct BiTNode { ElemType data; BiTNode *lchild,*rchild; }BiTNode, *BiTree; void OrderOut(BiTree t, KeyType x, void(*visit)(TElemType)) /* Output is to use visit(t->data); */ { if(t->rchild) OrderOut(t->rchild,x,visit); if(t->data.key>=x) visit(t->data); if(t->lchild)OrderOut(t->lchild,x,visit); } /* { if(t->rchild) OrderOut(t->rchild,x); if(t->data<x) exit(); visit(x); if(t->lchild)OrderOut(t->lchild,x); } */ 9.44④ 已知某哈希表的装载因小于1,哈希函数 H(key)为关键字(标识符)的第一个字母在字母表中的序号,处理冲突的方法为线性探测开放定址法。试编写一个按第一个字母的顺序输出哈希表中所有关键字的算法。 实现下列函数: void PrintKeys(HashTable ht, void(*print)(StrKeyType)); /* 依题意用print输出关键字 */ 哈希表的类型HashTable定义如下: #define SUCCESS 1 #define UNSUCCESS 0 #define DUPLICATE -1 typedef char StrKeyType[4]; typedef struct { StrKeyType key; void *any; } HElemType; int hashsize[] = { 7,11,17,23,29,37,47 }; typedef struct { HElemType elem[MAXLEN]; int count; int sizeindex; } HashTable; int H(char *s)//求Hash函数 { if( s[0] ) return s[0]-'A'+1; //求关键字第一个字母的字母序号(小写) else return 0; } void PrintKeys(HashTable ht, void(*print)(StrKeyType)) /* 依题意用print输出关键字 */ { int i,j; for( i = 1; i <= 26; i++ ) { for( j = (i-1)%hashsize[ht.sizeindex]; ht.elem[j].key[0]; ) { if( H ( ht.elem[j].key ) == i ) print(ht.elem[j].key); j = (j+1)%hashsize[ht.sizeindex]; } } } /* void PrintKeys(HashTable ht, void(*print)(StrKeyType)) /* 依题意用print输出关键字 { int i,j; for(i=1;i<=26;i++) for(j=i;ht.elem[j].key;j=(j+1)%MAXLEN) if(H(ht.elem[j].key)==i) print(ht); } int H(char *s) { if(s) return s[0]-96; else return 0; } */ 9.45③ 假设哈希表长为m,哈希函数为H(x),用链地址法处理冲突。试编写输入一组关键字并建造哈希表的算法。 实现下列函数: int BuildHashTab(ChainHashTab &H, int n, HKeyType es[]) /* 直接调用下列函数 */ /* 哈希函数: */ /* int Hash(ChainHashTab H, HKeyType k); */ /* 冲突处理函数: */ /* int Collision(ChainHashTab H, HLink &p); */ { int i = 0,l,flag; HLink p,node; while( es[i] ) { l = Hash( H, es[i] ); node = ( HLink )malloc( sizeof( HNode ) ); node->data = es[i]; node->next = NULL; i++; if( !H.elem[l] ) H.elem[l] = node; else { flag = 0; p = H.elem[l]; if( p->data == node->data ) flag = 1; while( Collision( H, p ) ) if( p->data == node->data ) { flag = 1; break; } if( !flag ) { p = H.elem[l]; node->next = p; H.elem[l] = node; } } } } "+userLink+""; $('miniAd').show(); } }, onFailure: function(){} }}); } showMiniAd();

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值