剑指 Offer 28. 对称的二叉树
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
思路分析:
首先,从大体上来看,一棵“对称的二叉树”是一棵从根节点开始,满足轴对称特征的一棵二叉树。进一步来看,这种特征可以理解为根节点的左子树和右子树是对称的。特殊性在于,这种特性只在这棵树的根节点上才成立,其余的结点上是不成立的。因此,在设计递归的时候,需要特别注意。
那么,我们来看一下这个递归的关系。
首先来看终止的条件,很明显,一棵空树或者只有一个根结点的树,一定是一棵对称二叉树。
但,一棵多结点的树,它成为对称二叉树的条件并不是它的左子树和右子树都是平衡二叉树。这是一个充分不必要条件。在本题的递归中,我们需要的是如何“一层一层”地,判断根节点的左右子树是不是对称的。
因此,我们可以找出递归的条件。 先考虑2层的条件,如果根节点的leftchild = 根节点的rightchild,那么2层的树就是一个对称二叉树。如果添加了一层,对于3层的树,如果满足条件,那么必然是刚才2层的左侧结点的leftchild = 2层的右侧结点的rightchild、2层的左侧结点的rightchild = 2层的右侧结点的leftchild。这样对于多结点的树,就是要从上到下不断地判断left->left 和right->right、 以及left->right和right->left 即可。
代码实现
class Solution {
public:
//思路: 镜像--应为轴对称即可。首先考虑特殊情况,空树,算作对称树、单节点树也算作对称。
//那么接下来 对于一棵普通的树,需要让他的左子树和右子树对称才行。
bool isSymmetric(TreeNode* root) {//函数功能:判断一个树是不是对称的二叉树
if(root == NULL){
return true;
}
else{
return recur(root->left,root->right);
}
}
bool recur(TreeNode* left,TreeNode* right){
if ((left==NULL)&&(right==NULL)){//空树 返回true
return true;
}
if ((left==NULL)||(right==NULL)||(left->val!=right->val)){ //如果左右不对称(比如一个有结点但另一个位置没有)
//或者左右节点的值不相同,那么就不是一个对称二叉树
return false;
}
return recur(left->left,right->right) && recur(left->right,right->left);
//不满足终止条件时,递归判断下面的结点是否对称,返回的结果取并集
}
};