问题描述:
一棵二叉树,若其与自己的镜像完全相同,就称其为镜像树(即这棵二叉树关于根完全对称)。例如
是一棵镜像树;
而
不是镜像树。
现给你一棵二叉树,请你判断其是不是镜像树。
第一行是一个整数数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;
}