题目描述
LeetCode传送门:101. 对称二叉树
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
进阶:
你可以运用递归和迭代两种方法解决这个问题吗?
题目分析
容易看出一颗二叉树如果是对称的,那么它的根结点的左右子树也是对称的,而两个子树如果对称,则他们的左右子树也是对称的...根据这个思路可以想到这个题目应用递归法解题,而相应的也可以使用栈或队列实现非递归(迭代法)求解。
代码
递归法
递归法需要注意的是返回值的写法,对称比较的是左子树的左孩子与右子树的右孩子、左子树的右孩子与右子树的左孩子是否对称,同时对空结点也要有考虑。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool Symmetric(struct TreeNode* p, struct TreeNode* q)
{
if(!p || !q) //如果其中有一个结点为空
return p==q; //则判断这两个结点是否同时为空并将结果返回
if(p->val != q->val) //如果两结点所存储的值不等
return false; //返回false
/**
*递归判断(p结点的左子树和q结点的右子树)
*和(p结点的右子树和q结点的左子树)
*这两个条件是否成立,成立返回true,否则返回false
*/
return (Symmetric(p->left,q->right) && Symmetric(p->right,q->left));
}
bool isSymmetric(struct TreeNode* root){
if(!root)
return true;
return Symmetric(root->left,root->right); //判断左右子树是否对称
}
迭代法
迭代法使用队列,思路同递归法比较相似,同样需要注意四个孩子的入队顺序。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool isSymmetric(struct TreeNode* root){
if(!root)
return true;
if(!root->left && !root->right)
return true;
if(!root->left || !root->right)
return false;
struct TreeNode* q1[512]; //初始化队列
struct TreeNode* q2[512];
int front1, rear1, front2, rear2; //定义头尾指针
front1 = rear1 = front2 = rear2 = -1;
q1[++rear1] = root->left; //左右子树的根结点入队
q2[++rear2] = root->right;
struct TreeNode *p, *q; //临时结点p、q
while(front1 < rear1){ //队列非空时
p = q1[++front1]; //出队
q = q2[++front2];
if(!p && !q) //两结点均为空结点时跳过本次循环
continue;
if((!p || !q) || (p->val != q->val)) //一旦一空一不空或值不等,则不对称,返回false
return false;
q1[++rear1] = p->left; //同递归法
q1[++rear1] = p->right; //左子树先左后右入队
q2[++rear2] = q->right; //右子树先右后左入队
q2[++rear2] = q->left;
}
return true;
}