一、题目解析
请实现一个函数,用来判断一棵二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
判断一棵二叉树是否是对称的,主要判断该二叉树的左子树和右子树是否对称即可
(1)如果二叉树的根节点为空,则符合条件
(2)递归判断二叉树的左子树的左节点和右子树的右节点,左子树的右节点和右子树的左节点是否相等。
二、递归代码
class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val)
{
this.val =val;
}
}
public class Test_15 {
boolean isSymmetrical(TreeNode pRoot) {
//二叉树为空
if (pRoot == null) {
return true;
}
return isSymmetrical(pRoot.left, pRoot.right);
}
private boolean isSymmetrical(TreeNode left, TreeNode right) {
//左右节点均为空
if (left == null && right == null) {
return true;
}
//左右节点有一个为空
if (left == null || right == null) {
return false;
}
//递归判断
return left.val == right.val
&& isSymmetrical(left.left, right.right)
&& isSymmetrical(left.right, right.left);
}
}
三、非递归代码:DFS 深度优先遍历
DFS 使用 stack 来保存成对的节点
(1)出栈的时候需要成对成对的
(2)若都为空,继续
(3)一个为空直接返回false,否则都不为空比较当前值是否相等。
(4)每次入栈需要成对的:左子树的左节点和右子树右节点;左子树的右节点和右子树的左节点;
boolean isSymmetricalDFS(TreeNode pRoot)
{
if(pRoot == null) return true;
Stack<TreeNode> s = new Stack<>();
s.push(pRoot.left);
s.push(pRoot.right);
while(!s.empty()) {
TreeNode right = s.pop();//成对取出
TreeNode left = s.pop();
if(left == null && right == null) continue;
if(left == null || right == null) return false;
if(left.val != right.val) return false;
//成对插入
s.push(left.left);
s.push(right.right);
s.push(left.right);
s.push(right.left);
}
return true;
}
四、非递归代码:BFS 广度优先遍历
BFS 使用 Queue 来保存成对的节点
(1)成对出队
(2)都为空,继续判断,有一方为空返回false
(3)同样每次入队都要成对:左子树的左节点和右子树右节点;左子树的右节点和右子树的左节点;
boolean isSymmetricalBFS(TreeNode pRoot)
{
if(pRoot == null) return true;
Queue<TreeNode> s = new LinkedList<>();
s.offer(pRoot.left);
s.offer(pRoot.right);
while(!s.isEmpty()) {
TreeNode left= s.poll();//成对取出
TreeNode right= s.poll();
if(left == null && right == null) continue;
if(left == null || right == null) return false;
if(left.val != right.val) return false;
//成对插入
s.offer(left.left);
s.offer(right.right);
s.offer(left.right);
s.offer(right.left);
}
return true;
}