有关二叉树的一些练习题

二叉树的第三部分

这一部分 是 有关一些 二叉树 的 练习题

相同的树

在这里插入图片描述
附上代码

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
       if(p!= null && q == null || p == null && q != null) {
            return false;
        }
        
        if(p == null && q == null ) {
            return true;
        }
        if(p.val != q.val) {
            return false;
        }
        
       return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
    }
}

时间复杂度

在来一个 小问题 这 函数 的时间复杂度 为 多少

这里我们都要遍历两颗树的结点 ,这里 需要看一下p和 q 的每棵树的结点个数

这里求 p 的 结点M 和 q 的 结点树N 的最小值

0(min(M,N))

看完了相同的 树那么接下来 来看 一道类似的题目

另一棵树的子树

在这里插入图片描述
在这里插入图片描述
附上代码

class Solution {
    private boolean isSamTree(TreeNode p,TreeNode q) {
        if(p == null && q != null || p != null && q == null) {
            return false;
        }
        if(p == null && q == null) {
            return true;
        }
        if(p.val != q.val) {
            return false;
        }
        return isSamTree(p.left,q.left) && isSamTree(p.right,q.right);
    }
    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        if(root == null || subRoot == null) {
            return false;
        }
        // 根结点和 subroot是不是两颗相同的树
        if(isSamTree(root,subRoot)) {
            return true;
        }
        //subRoot 是不是 root 的左子树
        if(isSubtree(root.left,subRoot)) {
            return true;
        }
        if(isSubtree(root.right,subRoot)) {
            return true;
        }
        return false;
        
    }
}

时间复杂度

这里 需要 root 的每个结点 与 subRoot 比较 所以 如果 root 有 S 个结点 subRoot 有 T 个结点,每个 S都需要去 T 比较

所以时间复杂度 就为0(S * N)

平衡二叉树

在这里插入图片描述
附上代码

class Solution {
       public int height(TreeNode root) {
        if(root == null) {
            return 0;
        }
        int leftHeight = height(root.left);
        int rightHeight = height(root.right);
        return Math.max((leftHeight+1),(rightHeight+1));
    }
    // 判断连个树是否为 平衡二叉树
    public boolean isBalanced(TreeNode root) {
        if(root == null) {
            return true;
        }
        int left = height(root.left);
        int right = height(root.right);
        return    Math.abs(left - right) <= 1 && isBalanced(root.left) && isBalanced(root.right);
    }
}

优化后

class Solution {
       public int height(TreeNode root) {
        if(root == null) {
            return 0;
        }
        int leftHeight = height(root.left);
        int rightHeight = height(root.right);
        if(leftHeight >=0 && rightHeight >=0 && Math.abs(leftHeight - rightHeight) <=1) {
            return Math.max(leftHeight,rightHeight) + 1;
        }else {
            return -1;
        }
    }
    public boolean isBalanced(TreeNode root) {
        if(root == null) {
            return true;
        }
        return height(root) >=0;
    }
}

对称二叉树

在这里插入图片描述
在这里插入图片描述
附上代码

class Solution {
    //创建一个方法,用来判断root的左树和 右数
    public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree) {
        if(leftTree == null && rightTree != null || leftTree != null && rightTree == null) {
            return false;
        }
        if(leftTree == null &&rightTree == null) {
            return true;
        }
        if(leftTree.val == rightTree.val) {
            return isSymmetricChild(leftTree.left,rightTree.right) &&isSymmetricChild(leftTree.right,rightTree.left);
        }
        return false;
    }
    public boolean isSymmetric(TreeNode root) {
      if(root == null) return true;
      return isSymmetricChild(root.left,root.right);
    }
}

创建一颗二叉树

回忆上面我们创建一颗二叉树是不是 通过 穷举 来创建的一颗二叉树,那么 现在我们来使用先序遍历来创建一颗二叉树

二叉树遍历

在这里插入图片描述
附上代码

import java.util.Scanner;
import java.util.*;
class TreeNode{
    public char val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(char val) {
        this.val = val;
    }
}
public class Main{
    
    public static int i= 0;
    public static TreeNode createTree(String str) {
        
        TreeNode root = null;
        if(str.charAt(i) != '#') {
            root = new TreeNode(str.charAt(i));
            i++;
            root.left = createTree(str);
            root.right = createTree(str);
        }else {
            i++;
        }
        return root;
    }
    public static void inorter(TreeNode root){
        if(root == null) {
            return;
        }
        inorter(root.left);
        System.out.print(root.val+" ");
        inorter(root.right);
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 这里需要注意hasNext 与 hasNextLine 的区别
        // hasNextLine 遇到空格不结束
        // hasNext 遇到空格结束
        while(sc.hasNextLine()) {
            String str = sc.nextLine();
            TreeNode root = createTree(str);
            inorter(root);
        }
   

​ 最后来补充一下之前的程序 遍历 ,回忆一下 上文 写 的 判断一颗完全二叉树

其实程序遍历也是 这个思路 通过 一个队列,为空 就 不 加入队列,

程序遍历

 // 程序遍历
    public void levelOrder(TreeNode root) {
        if(root == null) {
            return;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            TreeNode tmp = queue.poll();
            System.out.print(tmp.val+ " ");
            if(tmp.left!= null) {
                queue.offer(tmp.left);
            }
            if(tmp.right != null) {
                queue.offer(tmp.right);
            }
        }
    }

在这里插入图片描述
写 完了 程序遍历那么我们上 力扣 上写一下oj题嘿嘿

二叉树的层序遍历

class Solution {
     public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> list = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        if(root == null) return list;
        while(!queue.isEmpty()) {
           int size = queue.size();
            List<Integer> list2 = new ArrayList<>();
            while(size != 0) {
                TreeNode tmp = queue.poll();
                list2.add(tmp.val);
                if(tmp.left != null) {
                    queue.offer(tmp.left);
                }
                if(tmp.right != null) {
                    queue.offer(tmp.right);
                }
                size--;
            }
            list.add(list2);
        }
        return list;
    

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值