【机试书】判断两棵树是否为同一棵树

由于一种遍历顺序不能唯一地确定一棵树,所以两颗不同的树的某一种遍历顺序是可能相同的,比如数字相同但插入顺序不同的两棵二叉排序树,中序遍历的结果是相同的。

结论:对两棵树进行包括中序遍历在内的两种遍历(如中序+前序遍历),若两种遍历的结果都相同,则可以判定两棵树相同。

 

进行前序遍历+中序遍历,将遍历结果存到char数组中,最后用strcmp来比较。(为了使用strcmp,在比较前要在char数组末尾加一个char[tail]='\0',表示字符串到达末尾)

AC代码:

#include<iostream>
#include<bits/stdc++.h> 
using namespace std;

struct treeNode
{
	int val;
	treeNode* left;
	treeNode* right;
	treeNode(int x):val(x),left(NULL),right(NULL){}	
};

void insertTree(treeNode* &t, int a) //注意这里传引用&t,防止修改无效 
{
	if(t==NULL) //如果是空,创建该结点
	{
		t = new treeNode(a);
	} 
	else if(t->val>a) //a应该在左子树
	{
		insertTree(t->left,a);  
	} 
	else if(t->val<a)//a应该在右子树 
	{
		insertTree(t->right,a);
	}
}

char str1[50],str2[50];//将前序遍历+中序遍历的结果序列相连接保存到一个字符数组中,方便strcmp 
int cnt1=0,cnt2=0;

//中序遍历 
void inOrder(treeNode*head,int number) //number:之后输入的要来比较的,Number=2 
{
	if(head->left!=NULL)
		inOrder(head->left,number);
		
	if(number==1)
		str1[cnt1++] = head->val + '0';
	else if(number==2)
		str2[cnt2++] = head->val + '0';
		
	if(head->right!=NULL)
		inOrder(head->right,number); 
}

//前序遍历 
void preOrder(treeNode*head,int number) //number:之后输入的要来比较的,Number=2 
{
	if(number==1)
		str1[cnt1++] = head->val + '0';
	else if(number==2)
		str2[cnt2++] = head->val + '0';
	
	if(head->left!=NULL)
		preOrder(head->left,number);
	
	if(head->right!=NULL)
		preOrder(head->right,number); 
}


int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		if(n==0)
			break;
		//首先是这个要被比较的树 
		treeNode *root = NULL; 
		string s;
		cin>>s; //注意这里输入的是当作字符串~因为它没有空格只看回车 
		for(int i=0;i<s.length();i++)
			insertTree(root,s[i]-'0');
		
		//不用清空str1了,只需要初始化cnt1。因为可以直接覆盖,然后strcmp比较之前+个'\0'表示结束 
		cnt1=0; 
		//前序+中序遍历
		preOrder(root,1);
		inOrder(root,1);
		str1[cnt1]='\0';
		
		//然后输入要过来比较的树 
		for(int i=0;i<n;i++)
		{
			treeNode *r = NULL; 
			string s1;
			cin>>s1;
			for(int j=0;j<s1.length();j++)
				insertTree(r,s1[j]-'0'); //竟然在这里粗心把s1写成s了,这种粗心太可怕了,耽误很多时间,一定要细心啊!
			cnt2=0;
			preOrder(r,2);
			inOrder(r,2);
			str2[cnt2]='\0';
			
			//二者相比
			if(strcmp(str1,str2)==0) 
				cout<<"YES"<<endl; 
			else
				cout<<"NO"<<endl; 
		}
	}
	return 0;
}

 

但是呢,其实可以不用这种方法做,还有更简单的方法——递归,一个结点一个结点地比较

我也是惊了,其实就下面这个函数就可以AC:

bool isEqual(treeNode* a,treeNode* b)
{
    if(a==NULL&&b==NULL) //都到空了,相等了
        return true;
    if((a==NULL&&b!=NULL)||(a!=NULL&b==NULL)) //一方为空一方不为空,说明不相等
        return false;
    if(a->val!=b->val)
        return false;
    return isEqual(a->left,b->left) && isEqual(a->right,b->right); 
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值