1.二叉树的遍历
给定一棵二叉树,要求返回它的前序遍历/中序遍历和后序遍历。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
//前序遍历
class Solution {
private ArrayList<Integer> list;
public List<Integer> preorderTraversal(TreeNode root) {
list=new ArrayList<Integer>();
preorder(root);
return list;
}
private void preorder(TreeNode root){
if(root!=null){
list.add(root.val);
preorder(root.left);
preorder(root.right);
}
}
}
//中序遍历
class Solution {
private ArrayList<Integer> list;
public List<Integer> inorderTraversal(TreeNode root) {
list=new ArrayList<Integer>();
inorder(root);
return list;
}
private void inorder(TreeNode root){
if(root!=null){
inorder(root.left);
list.add(root.val);
inorder(root.right);
}
}
}
//后序遍历
class Solution {
private ArrayList<Integer> list;
public List<Integer> postorderTraversal(TreeNode root) {
list=new ArrayList<Integer>();
postorder(root);
return list;
}
private void postorder(TreeNode root){
if(root!=null){
postorder(root.left);
postorder(root.right);
list.add(root.val);
}
}
}
2.查看两棵树是否相同
思路:两棵树的根结点的值、左子树和右子树都相同,才相同。
特殊情况:两棵树都为空,相同;只有一棵树为空,不相同。
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p==null&&q==null){
return true;
}
if(p==null||q==null){
return false;
}
return p.val==q.val&&isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
}
}
3.对称二叉树
如图,为对称二叉树。
如上图,(1)和(2)互为镜像二叉树。由此可知:对称二叉树的根结点相同,左子树和右子树的左右孩子结点恰恰相反。(互为镜像二叉树)
思路:判断根结点的左右子树是否为镜像二叉树。镜像二叉树的特点:根结点相同,左孩子结点和右孩子结点的值恰好相反。
特殊情况:根结点为空或者只有一个根结点,则为对称二叉树。
class Solution {
public boolean isSymmetric(TreeNode root) {
if((root==null)||(root.left==null&&root.right==null)){
return true;
}
return isMirror(root.left,root.right);
}
private boolean isMirror(TreeNode p,TreeNode q){
if(p==null&&q==null){
return true;
}
if(p==null||q==null){
return false;
}
return p.val==q.val&&isMirror(p.left,q.right)&&isMirror(p.right,q.left);
}
}
4.1 另一棵树的子树
题目描述:给定两个非空二叉树s和t,检验s中是否包含和t具有相同结构和结点值的子树。s的一个子树包括s的一个节点和这个节点的所有子孙。s也可以看做它自身的一棵子树。如:
又如:
思路:不断遍历s树的每个结点,判断该结点和它所有孩子结点组成的子树是否和t树相同,转化为判断两棵树相同的问题。
特殊情况:如果两个树均为空,则返回true;如果有一个为空,一个不为空,则返回false。
class Solution {
private boolean isSame(TreeNode p,TreeNode q){
if(p==null&&q==null){
return true;
}
if(p==null||q==null){
return false;
}
return p.val==q.val&&isSame(p.left,q.left)&&isSame(p.right,q.right);
}
private boolean find(TreeNode root,TreeNode t){
if(root==null){
return false;
}
if(isSame(root,t)){
return true;
}
//在左子树中找
if(find(root.left,t)){
return true;
}
//在右子树中找
return find(root.right,t);
}
public boolean isSubtree(TreeNode s, TreeNode t) {
return find(s,t);
}
}
4.2 树的子结构
输入两棵二叉树A,B,判断B是不是A的子结构。(PS:我们约定空树不是任意一个树的子结构)。
思路:如果A树为空,则B树一定不是A的子结构;如果B树为空,则B树也一定不是A树的子结构。然后依次以A树的每个结点为根节点,比较B树是否是以根节点构成的子结构。子结构的判定:如果B树为空,说明B树比较到叶子结点,则B树是子结构;如果B不为空且A树为空,或者A树的值不是B树的值,则说明B树不是A树的子结构。如果A树不为空且B树不为空,则依次比较B的左子树是否是A的左子树、B的右子树是否是A的右子树,如果都是,才返回true;否则返回false。
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root1==null||root2==null){
return false;
}
//依次判断当前root2是否是root1这棵树的子结构、root1.left的子结构、root1.right的子结构
return isSubTree(root1,root2)||HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2);
}
private boolean isSubTree(TreeNode root1,TreeNode root2){
//如果root2=null,说明已经比较到最后位置,返回true。
if(root2==null){
return true;
}
//如果root1==null,说明不是子结构
if(root1==null||root1.val!=root2.val){
return false;
}
//否则比较左子树的结构和右子树的结构
return isSubTree(root1.left,root2.left)&&isSubTree(root1.right,root2.right);
}
}