镜像树(XCOJ 1214)

问题描述:

一棵二叉树,若其与自己的镜像完全相同,就称其为镜像树(即这棵二叉树关于根完全对称)。例如

是一棵镜像树;

不是镜像树。
现给你一棵二叉树,请你判断其是不是镜像树。

输入:

第一行是一个整数数T,表示测试数据有多少组
每组数据第一行是一个正整数n(1<=n<=100),表示二叉树中节点的数量
下面n行,每行有三个正整数a b c(1<=a<=100,0<=b,c<=100),表示以编号a的节点为父节点,它的左孩子节点编号为b,右孩子节点编号为c,若b=0表示没有左孩子节点,c=0表示没有右孩子节点,树的根节点是编号为1的节点,节点的编号都>=1(保证数据中给出的二叉树拓扑结构是合法的)
下面一行是n个正整数vi(1<=vi<=100),表示编号为i的节点的值。


输出:

若数据中表示的二叉树是镜像树,输出“Yes”,否则输出“No”,每个输出单独占一行


样例输入:
2
7
1 2 3
2 4 5
3 6 7
4 0 0
5 0 0
6 0 0
7 0 0
1 2 2 3 4 4 3
5
1 2 3
2 0 4
3 0 5
4 0 0
5 0 0
1 2 2 3 3


样例输出:

Yes

No


分析:

这是一道简单的二叉树题,只要利用递归的思想写判断函数即可,有一个点要注意,就是当此二叉树只有一个结点时,那么他显然是镜像树,但是如果在进一步的递归处理中没有子树即叶子节点是递归的终止条件,所以分成了两个函数,递归主体单独为一个函数。

代码:


#include<iostream>
#include<string>
#include<cstring>
#define local
using namespace std;

struct bnode{ 
	int data;  //数据
	struct bnode *lc,*rc;  //左孩子,右孩子指针 
};
typedef bnode* bitre;

bool search(bitre lc,bitre rc){
	//递归终止条件 
	if(lc==NULL && rc==NULL)
		return true;
	//不是镜像树直接返回 
	if(lc==NULL || rc==NULL)
		return false;
	//对左右子树进行递归判断 
	return (lc->data == rc->data) && search(lc->lc,rc->rc) && search(lc->rc,rc->lc);
}

bool isSymmetric(bitre t){
	//如果是无子树二叉树则直接返回true 
	if(t->lc==NULL && t->rc==NULL)
		return true;
	return search(t->lc,t->rc);
}

int main(){
	#ifdef local
	freopen("镜像树.in","r",stdin);
	//freopen("镜像树.out","w",stdout);
	#endif
	int m;
	cin>>m;
	for(int k=0;k<m;k++){
		int n;
		cin>>n;
		bitre *t=new bitre[n+1]; //树结点数组 
		for(int i=1;i<=n;i++){
			t[i]=new bnode;
			//t[i]->order=i;
			t[i]->lc=NULL;
			t[i]->rc=NULL;
		}
		for(int i=0;i<n;i++){
			int a,b,c;
			cin>>a>>b>>c;
			if(b!=0){
				t[a]->lc=t[b];
			}
			if(c!=0){
				t[a]->rc=t[c];
			}
		}
		for(int i=1;i<=n;i++){
			int d;
			cin>>d;
			t[i]->data=d;
		}
		if(isSymmetric(t[1]))
			cout<<"Yes"<<endl;
		else
			cout<<"No"<<endl;
	} 
	return 0;
} 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值