对称二叉树,以根节点为中心如下图所示的对称节点的值是相同的。
一、递归方式判断二叉树是否是对称二叉树
1.首先递归的终止条件就是两个比较节点为null或者两个比较节点其中一个为null或者两个比较节点的值不同。
2.递归进行子节点比较,两个比较子节点的值必须相同,左子节点的左子节点必须等于右子节点的右子节点,左子节点的右子节点必须等于右子节点的左子节点。如上图所示
bool isSymmetric(struct TreeNode* root){
if(root==NULL){
return true;
}
// 比较左右子节点
return isSymmetricTree(root->left,root->right);
}
bool isSymmetricTree(struct TreeNode* left,struct TreeNode* right){
// 递归终止条件 当前是叶子节点
if(left==NULL&&right==NULL){
return true;
}
// 如果比较的两个节点有一个为空或者两个节点值不相同直接返回false
if(left==NULL||right==NULL||left->val!=right->val){
return false;
}
// 比较左子树与右子树的值,比较左子树的右子树和右子树的左子树的值
return isSymmetricTree(left->left,right->right)&&isSymmetricTree(left->right,right->left);
}
二、非递归方式判断对称二叉树(我们使用队列这个数据结构来解决这个问题)
1.树不为空树,根节点的左右子节点入队
2.队列不为空,队列元素出队一次出两个。
3.如果两个元素都为null,执行2。
4.如果其中有一个元素是null直接返回false。
5.如果其中两个元素不相等直接返回false。
6.第一个元素的左结点入队,第二个元素的右节点入队,第一个元素的右节点入队,第二个元素的左结点入队,执行2。
7.直至循环结束返回true,表示是对称二叉树。
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) {
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public boolean isSymmetric(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
// 空树
if (root == null)
return true;
// 根节点的左右子节点分别入队
queue.add(root.left);
queue.add(root.right);
// 队列不为空
while (!queue.isEmpty()) {
// 左右节点分别出队
TreeNode left = queue.poll();
TreeNode right = queue.poll();
// 如果这两个节点为null,继续执行循环有可能节点为子节点,也有可能这个两个节点没有左节点和右节点,队列还有其他元素。
if (left == null && right == null)
continue;
// 如果这两个节点有一个为空,就说明不对称
if (left == null||right == null)
return false;
// 如果这两个节点的值不同,就说明不对称
if (left.val != right.val)
return false;
// 左节点的左子节点入队 ---1
queue.add(left.left);
// 右节点的右子节点入队 ---2 1,2两节点比较
queue.add(right.right);
// 左节点的右子节点入队 ---3
queue.add(left.right);
// 右节点的左子节点入队 ---4 3,4两节点比较
queue.add(right.left);
}
return true;
}