二叉搜索树判断子树相等

1 篇文章 0 订阅

二叉搜索树

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2375    Accepted Submission(s): 1030

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

思路:给出两个序列,以二叉搜索树的方式建树(建树方法见博客中的其它文章),然后判断两棵二叉搜索树是否相同,相同则输出YES,或者输出NO.

一开始的思路是,先建立两棵树,然后求出它们的先序和中序,比较相应的序列是否相同,则可以判断,但是这种办法是超时的,原因也比较明显,因为要多次递归。

因此,换成另一种思路,直接写一个判断两棵子树是否相同的子程序即可。

/*
First time,I used inorde and preorder to judge if it's Yes or No,but Time Limit Exceeded,
Second time,I change to isEqual(),then ,it's done.
*/
#include <iostream>
#include <string>
#include <limits.h>
using namespace std;

struct node
{
	char key;
	node* left;
	node* right;
	node(char k):key(k),left(NULL),right(NULL){}
};

void insert(node** root,node* z)
{
	node *y = NULL, *x = *root;
	while(x)
	{
		y = x;
		if( y->key < z->key )
			x = x->right;
		else x = x->left;
	}
	if ( y == NULL )
		*root = z;
	else if (y->key < z->key )
		y->right =z;
	else
		y->left = z;
}

void Del(node* root )
{
	if( root != NULL)
	{
		Del(root->left);
		Del(root->right);
		delete root; //Can't exchange order,can't put delete front or middle
	}
}

bool isEqual(node* root1,node* root2)
{
	if ( root1 != NULL && root2 != NULL)
	{
		if ( root1->key != root2->key )
			return false;
		return (isEqual(root1->left,root2->left) 
			&& isEqual(root1->right,root2->right));
	}
	else
	{
		if( root1 == NULL && root2 == NULL )
			return true;
		else
			return false;
	}
}

int main()
{
	int T,i;
//	string line, stdIn = "", stdPre = "", In = "", Pre = "";
	string line;
	node *root1 = NULL,*root2 = NULL;

	while(cin >> T && T!=0)
	{
		getchar(); //to get '\n' in the end
		getline(cin,line);

		root1 = NULL;

		for(i=0; i<line.size(); ++i)
		{
			insert(&root1,new node(line[i]));
		}

	//	InOrder(root,stdIn);
	//	PreOrder(root,stdPre);
	//	Del(root); // void Memory leaks

		while( T -- )
		{
			getline(cin,line);
			root2 = NULL;
			for(i=0; i<line.size(); ++i)
			{
				insert(&root2,new node(line[i]));
			}
			if( isEqual(root1,root2) )
				cout << "YES" << endl;
			else
				cout << "NO" << endl;
			
		//	In = "";
		//	InOrder(root,In);
		//	Del(root);

		//	if ( In != stdIn )
		//	{
		//		cout << "NO" << endl;
		//		continue;
		//	}
		//	root = NULL;
		//	Pre = "";
		//	PreOrder(root,Pre);
		//	Del(root);

		//	if (Pre != stdPre )
		//	{
		//		cout <<"NO" << endl;
		//		continue;
		//	}
		//	cout << "YES" << endl;
		}
	}
	return 0;
}

/*
void InOrder(node* root,string& str)
{
	if( root != NULL)
	{
		InOrder(root->left, str);
		str.push_back(root->key);
		InOrder(root->right, str);
	}
}

void PreOrder(node* root,string& str)
{
	if( root != NULL)
	{
		str.push_back(root->key);
		PreOrder(root->left,str);
		PreOrder(root->right,str);
	}
}
*/


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Raise

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值