最近做了一些关于二叉树的算法题目,在这里我给大家分享一个比较简单的问题:判断两个二叉树是否相同~
Given two binary trees, write a function to check if they are the same or not.
Two binary trees are considered the same if they are structurally identical and the nodes have the same value.
Example 1:
Input: 1 1 / \ / \ 2 3 2 3 [1,2,3], [1,2,3] Output: true
Example 2:
Input: 1 1 / \ 2 2 [1,2], [1,null,2] Output: false
Example 3:
Input: 1 1 / \ / \ 2 1 1 2 [1,2,1], [1,1,2] Output: false
刚看到这道题,我可能脑筋没转过弯吧,思维直接跑偏了,愣是想到了用队列遍历,然后一层一层比较两个树的元素是否相同,后来真的是越写越复杂啊,蓝瘦香菇,只能硬着头皮写完了,但细想了一下这么这道题不应该这么麻烦的吧,至少不用队列是完全可以做的,然后就想到了深度优先搜索遍历,用先中后序或递归遍历应该是会更简单一点,然后自己就试着写了一下代码,结果问题也就迎刃而解了,难度确实不大,不过我希望通过这道题呢,可以培养大家对于二叉树问题的解题思想,其实关于二叉树,几乎所有问题都需要用到遍历,这里我给大家延伸一下,分享一下我的先中后序以及层次遍历的Java实现:
先序遍历:
public void firstTraversal(TreeNode root) {//根左右
System.out.print(root.val+" ");
if(root.left!=null)
firstTraversal(root.left);
if(root.right!=null)
firstTraversal(root.right);
}
中序遍历:
public void middleTraversal(TreeNode root) {//左根右
if(root.left!=null)
middleTraversal(root.left);
System.out.print(root.val+" ");
if(root.right!=null)
middleTraversal(root.right);
}
后序遍历:
public void postTraversal(TreeNode root) {//左右根
/*if(root.left==null&&root.right==null) {
System.out.print(root.val+" ");//输出叶子结点
}*/
if(root.left!=null)
postTraversal(root.left);
if(root.right!=null)
postTraversal(root.right);
System.out.print(root.val+" ");
}
层次遍历:
public void levelTraversal(TreeNode root) {//借助队列层次遍历
Queue<TreeNode> q = new LinkedList<TreeNode>();
q.add(root);
while(!q.isEmpty()) {
TreeNode node = q.poll();
System.out.print(node.val+" ");
if(node.left!=null)
q.add(node.left);
if(node.right!=null)
q.add(node.right);
}
}
希望大家能够理解掌握这些遍历方式并能够熟练应用,那么了解了这些遍历方式后,我们再来看一下怎样去判断两棵树是否相同吧,这里我把自己用队列和递归遍历的实现都给大家分享一下哈~
队列层序遍历实现:
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p==null||q==null)
return p==q;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
Queue<TreeNode> queue2 = new LinkedList<TreeNode>();
queue.add(p);
queue2.add(q);
while(!queue.isEmpty()&&!queue2.isEmpty()) {
if(queue.size()!=queue2.size())
return false;
TreeNode node = queue.poll();
TreeNode node2 = queue2.poll();
if(node.val!=node2.val)
return false;
if(node.left!=null&&node2.left!=null) {
queue.add(node.left);
queue2.add(node2.left);
}
else if(node.left==null&&node2.left!=null)
return false;
else if(node.left!=null&&node2.left==null)
return false;
if(node.right!=null&&node2.right!=null) {
queue.add(node.right);
queue2.add(node2.right);
}
else if(node.right==null&&node2.right!=null)
return false;
else if(node.right!=null&&node2.right==null)
return false;
}
return true;
}
递归遍历实现:
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q == null) return true;
if(p == null || q == null) return false;
if(p.val == q.val)
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
return false;
}
差距已经形成了哈哈,不同的遍历方式体现出的代码复杂性显而易见,所以我们应该合理的运用多种二叉树的遍历方式解决问题,这将会决定我们的代码复杂性和可读性,当然不能说层序遍历复杂一些我们就不去学习,这几种遍历方式我们都应该熟练掌握哦,因为它们都是有各自的优点嘞~