JZ26 树的子结构
(较难)
题目
描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
示例
输入:
{8,8,#,9,#,2,#,5}, {8,9,#,2}
返回值:
true
思路
本题可用深度遍历实现,递归过程的思想为如果一棵树2属于另一棵树1,那么子树2一定可以在树1中找到一个结点,此结点也与子树2的根结点的值相等,并且遍历它们的左右子树,及子树的子树,发现值也是相等的。因为树1是“较大”的树,而子树2是“较小”的树,因此,如果子树2先遍历结束,那么就可以判断这种方向的递归为子树2是树1的子树这种情况,即if (root2 == null) return true;
;而如果树1先遍历结束,而树2未遍历结束,那么2肯定是不属于1的,因为树1已经遍历到头,而树2还有结点未遍历,即if (root1 == null) return false;
;同样的,如果当前遍历的树2与树1的结点的值不相等,即if (root1.val != root2.val) return false;
,那么此方向的遍历也肯定不是所属子树的情况,而具体递归的细节,我认为用文字表述反而不如代码直观,因此直接看代码即可。
实现
public class JZ26树的子结构 {
public boolean HasSubtree(TreeNode root1, TreeNode root2) {
if (root1 == null || root2 == null) {
return false;
}
if (isSubTree(root1, root2)) {
return true;
}
return HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2);
}
public boolean isSubTree(TreeNode root1, TreeNode root2) {
if (root2 == null) {
return true;
}
if (root1 == null || root1.val != root2.val) {
return false;
}
return isSubTree(root1.left, root2.left) && isSubTree(root1.right, root2.right);
}
}
JZ32 从上往下打印二叉树
(简单)
题目
描述
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
示例
输入:
{5,4,#,3,#,2,#,1}
返回值:
[5,4,3,2,1]
思路
本题考查树的层序遍历,是一道十分基础的题目,是一种广度优先遍历,可以利用一个辅助队列来解决,是很基础的一种遍历方式,可以首先向队列中加入树的根结点(如果不为空的话),然后在队列中元素数量大于 0 的情况下,不断出队列、判断此出队结点是否有左右孩子,有则入队到队尾,不断反复此操作,那么一定就是从上到下,从左到右的顺序出队元素,出队时用一个数组存储即可。(补充:关于图的层序遍历或者说是广度优先遍历,可参考之前文章:Java实现【邻接矩阵、邻接表的创建、遍历(DFS,BFS)】+图解+完整代码)。
实现
public class JZ32从上往下打印二叉树 {
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> list = new ArrayList();
if (root == null) {
return list;
}
ArrayList<TreeNode> queue = new ArrayList();
queue.add(root);
while (queue.size() != 0) {
TreeNode node = queue.remove(0);
list.add(node.val);
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
return list;
}
}