浙大数据结构——小白专场:是否同一棵二叉搜索树

本文探讨了如何判断不同插入序列是否能生成相同的二叉搜索树,提供了通过构建树进行比对的方法,以及一种不实际构建树的判别策略。详细介绍了树的构造、遍历和比较过程。

题意理解

给定一个插入序列就唯一确定一个二叉搜索树。

一棵给定的二叉搜索树却可以由多种不同的插入序列得到。

Q:对于输入的各种插入序列,如何判断它们能否生成一样的二叉搜索树?

求解思路

1、分别建二叉搜索树判别方法 

2、不建树的判别方法 

3、建一棵树,再判别其他序列是否与该树一致

搜索树的表示

typedef struct TreeNode *Tree;
struct TreeNode{
	int v;
	Tree Left,Right;
	int flag;    //代表有没有被访问过
}; 

程序框架搭建

int main(){
	int N,L,i;
	Tree T;
	scanf("%d",&N);
	while(N){
		scanf("%d",&L);
		//建搜索树 
		T=MakeTree(N);
		/判别 
		for(i=0;i<L;i++){
			if(Judge(T,N)){
				printf("Yes\n");
			}
			else{
				printf("No\n");
			}
			ResetT(T);
		}
		FreeTree(T);
		//输入下一轮要比较的序列的结点数 
		scanf("%d",&N);
	}
	return 0; 
}

建搜索树

Tree MakeTree(int N){
	Tree T;
	int i,V;
	
	scanf("%d",&V);
	//创建树,V为根节点 
	T=NewNode(V);
	for(i=1;i<N;i++){
		//输入的数插入到二叉搜索树中 
		scanf("%d",&V);
		T=Insert(T,V);
	}
	return T;	
} 

Tree NewNode(int V){
	Tree T=(Tree)malloc(sizeof(struct TreeNode));
	T->v=V;
	T->Left=T->Right=NULL;
	T->flag=0;
	return T;
} 

Tree Insert(Tree T,int V){
	if(!T){
		T=NewNode(V);
	}else{
		if(V>T->v){
			T->Right=Insert(T->Right,V);
		}else{
			T->Left=Insert(T->Left,V);
		}
	}
	return T;
}

判别

在创建好的搜索树中按顺序搜索序列中的每个树,如果每次所经过的结点在前面均出现过,则一致;否则,不一致。

int Judge(Tree T,int N){
	int i,V;
	int flag=0;	//0表示目前还一致,1表示已经不一致 
	scanf("%d",&V);
	if(V!=T->v){
		flag=1;
	}else{
		T->flag=1;
	}
	for(i=1;i<N;i++){
		scanf("%d",&V);
		if((!flag)&&(!check(T,V))){
			flag=1;
		}
	}
	if(flag){
		return 0;
	}
	else{
		return 1;
	}
}

int check(Tree T,int V){
	//如果查过当前结点 
	if(T->flag){
		if(V<T->v){
			return check(T->Left,V);
		}
		else if(V<T->v){
			return check(T->Right,V);
		}
		else{
			return 0;
		}
	}
	//如果没查过当前结点 
	else{
		if(V==T->v){
			T->flag=1;
			return 1;
		}
		else{
			return 0;
		}
	}
}

重置和释放

void ResetT(Tree T){
	if(T->Left){
		ResetT(T->Left);
	}
	if(T->Right){
		ResetT(T->Right);
	}
	T->flag=0;
}

void FreeTree(Tree T){
	if(T->Left){
		FreeTree(T->Left);
	}
	if(T->Right){
		FreeTree(T->Right);
	}
	free(T);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值