题目:
输入两颗二叉树A和B,推断B是不是A的子结构。
树的结构例如以下:
package com.aii.algorithm; public class TreeNode { int value; TreeNode left; TreeNode right; public TreeNode(int value) { this.value = value; } }
全在凝视上:
package com.aii.algorithm; public class HasSubTree { // 分两步: // 1.遍历 // 2.对于遍历到的节点与sub的根节点同样的。再细致比較 public boolean check(TreeNode root, TreeNode sub) { // 当前空,则返回false,表示遍历完了,都没找到。 if (root == null) { return false; } TreeNode current = root; // 先序遍历,先推断自己再说 if (current == sub) { // 假设是同样的,那就比較, // 假设比較成功,那就返回true, // 假设比較失败,也不能返回false,由于有可能这里不匹配剩下的有匹配的 // 全部是用if(boolean)return true而不用return boolean. if (checkThis(current, sub)) { return true; } } // 先序遍历到了左边。由于root为空的时候,则返回false // 而左没了还有右,所以不能直接check(root.left,sub) // 假设左没了,就找右。假设左有,就找找看 if (root.left != null) { if (check(root.left, sub)) { return true; } } // 最后到了右。无论怎么样 // 既然都到这了,说明中,左都没找到 // 所以能够直接return check(root.right,sub); return check(root.right, sub); } // 此方法用来推断当前的current节点是否包括sub节点,并且是一一相应的 // 即current=sub; // current.left=sub.left; // current.right=sub.right; private boolean checkThis(TreeNode current, TreeNode sub) { // sub为null。说明遍历完了。没找到不符合的,返回true if (sub == null) { return true; } // 这里也是採用递归遍历,先序遍历的方法 // 万一遇到一个不同的。返回false if (sub != current) { return false; } // 左边,与前面不同的是,先推断左边是不是有不同的,有就肯定是false。 // 没有也不代表是肯定同样。还得看右边 if (sub.left != null) { if (!checkThis(current.left, sub.left)) { return false; } } // 最后右边 return checkThis(current.right, sub.right); } }