二叉树高频题精讲 | 从入门到熟练掌握二叉树操作

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

本系列可作为JAVA学习系列的笔记,文中提到的一些练习的代码,小编会将代码复制下来,大家复制下来就可以练习了,方便大家学习。

点赞关注不迷路!您的点赞、关注和收藏是对小编最大的支持和鼓励! 

系列文章目录

JAVA初阶---------已更完

JAVA数据结构 DAY1-集合和时空复杂度

JAVA数据结构 DAY2-包装类和泛型

JAVA数据结构 DAY3-List接口

JAVA数据结构 DAY4-ArrayList

JAVA数据结构 DAY5-LinkedList

JAVA数据结构 DAY6-栈和队列

JAVA数据结构 DAY7-二叉树

JAVA数据结构 DAY8-堆

JAVA数据结构 DAY9 equals、Comparable、Comparator 与 PriorityQueue 深度解析

JAVA数据结构 DAY10-排序

JAVA数据结构 DAY11-Set和Map


拓展目录

手把手教你用 ArrayList 实现杨辉三角:从逻辑推导到每行代码详解

链表高频 6 题精讲 | 从入门到熟练掌握链表操作

二叉树高频题精讲 | 从入门到熟练掌握二叉树操作

二叉树高频题精讲 | 从入门到熟练掌握二叉树操作2

二叉树高频题精讲 | 从入门到熟练掌握二叉树操作3

Java 中的 hashCode () 与 equals () 核心原理、契约规范、重写实践与面试全解

Set&Map高频题精讲 | 从入门到熟练掌握


目录

目录

系列文章目录

拓展目录

目录

前言

1.二叉树的前序遍历(需要返回遍历完的节点)

法1:没有使用递归的返回值

法2:使用递归的返回值

2.完全二叉树的节点

法1:遍历二叉树 只要root不为空 ++

法2:子问题:整棵树有多少棵节点=左子树节点+右子树节点+1

3.整棵树的叶子节点

法1:遍历二叉树 只要root不为空 ++

法2:子问题:整棵树有多少棵叶子节点=左子树的叶子节点+右子树的叶子节点

 4.求第K层的节点个数

法1:遍历二叉树 只要root不为空 ++

法2:子问题:整层的节点=左子树的叶子节点+右子树的叶子节点

5.求第K层的节点个数

 6.值为value的元素是否存在

  7.层序遍历

核心原理(记住这 4 点)

 8.判断一棵树是否是完全二叉树

8.1 什么是完全二叉树?

8.2 判断核心规则(层序遍历)

总结


前言

小编作为新晋码农一枚,会定期整理一些写的比较好的代码,作为自己的学习笔记,会试着做一下批注和补充,如转载或者参考他人文献会标明出处,非商用,如有侵权会删改!欢迎大家斧正和讨论!

本节,我将分享一下二叉树的习题部分,以及思路详解,在力扣的运行环境,每一题将会附上练题链接,大家点击即可练习!

1.二叉树的前序遍历(需要返回遍历完的节点)

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

https://leetcode.cn/problems/binary-tree-preorder-traversal

提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

进阶:递归算法很简单,你可以通过迭代算法完成吗?

法1:没有使用递归的返回值

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    // 注意:变量名不要用List(大写L),和接口名重复了,改成小写list更规范
    List<Integer> list=new ArrayList<>();
    //在 Java 中,List 是一个定义了列表行为的接口,它只规定了 “列表应该能做什么”(比如 add()、get() 等方法),但并没有实现这些方法的具体逻辑。
    //接口本身不能被直接实例化(也就是不能写 new List<>()),因为它只是一个 “规范”,没有具体的执行代码。
    //List 是接口,仅定义规范,不能直接实例化(不能 new List<>());
    //ArrayList 是 List 接口的一个具体实现类,它用数组的方式实现了 List 接口中所有的方法(比如 add() 是往数组里加元素,get() 是从数组里取元素)。
    //所以我们需要通过 new ArrayList<>() 来创建一个具体的、可使用的列表对象,然后把它赋值给 List 类型的变量(这是 Java 的多态特性)。
    public List<Integer> preorderTraversal(TreeNode root) {
        if(root==null){
            return list;
        }
        list.add(root.val);
        preorderTraversal(root.left);
        preorderTraversal(root.right);
        return list;
    }
}

法2:使用递归的返回值

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<>();
        if(root==null){
            return list;
        }
        list.add(root.val);
        List<Integer> leftTree=preorderTraversal(root.left);
        list.addAll(leftTree);// 把左子树的遍历结果全部加入当前列表
        List<Integer> rightTree=preorderTraversal(root.right);
        list.addAll(rightTree);//// 把右子树的遍历结果全部加入当前列表

        return list;
    }
}

2.完全二叉树的节点

https://leetcode.cn/problems/count-complete-tree-nodes/

解法(其一):

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int countNodes(TreeNode root) {
        if(root==null){
            return 0;
        }
        return countNodes(root.left)+countNodes(root.right)+1;
    }
}

法1:遍历二叉树 只要root不为空 ++

public static int nodeSize=0;
    public void size(TreeNode root){
        if(root==null){
            return;
        }
        nodeSize++;
        size(root.left);
        size(root.right);
        return;
    }

main函数中做测试

public static void main(String[] args){
        //........
        binaryTree.size(root);
        System.out.println("节点的个数:"+BinaryTree.nodeSize);
}

法2:子问题:整棵树有多少棵节点=左子树节点+右子树节点+1

 public int size2(TreeNode root){
        if(root==null){
            return 0;
        }
        return size2(root.left)+size2(root.right)+1;
    }

main函数中做测试

System.out.println("节点的个数:"+binaryTree.size2(root));

3.整棵树的叶子节点

什么是叶子节点?

root.left==null&&root.right==null

整棵树的叶子节点=左子树的叶子+右子树的叶子

法1:遍历二叉树 只要root不为空 ++

public static int leefSize=0;
    public void getLeefNode2(TreeNode root){
        if(root==null){
            return;
        }
        if(root.left==null&&root.right==null){
            leefSize++;
        }
        getLeefNode2(root.left);
        getLeefNode2(root.right);
    }

main中调用

binaryTree.getLeefNode2(root);
System.out.println("叶子节点的个数:"+BinaryTree.leefSize);

法2:子问题:整棵树有多少棵叶子节点=左子树的叶子节点+右子树的叶子节点

//寻找树的叶子结点

    public int getLeefNode(TreeNode root){
        if(root==null){
            return 0;
        }
        if(root.left==null&&root.right==null){
            return 1;
        }
        return getLeefNode(root.left)+getLeefNode(root.right);

    }

 4.求第K层的节点个数

法1:遍历二叉树 只要root不为空 ++

//获取第K层结点的个数
    //遍历二叉树
    public static int KLevelnodes=0;
    public int getKLevelNodeCount(TreeNode root,int k){
        if(root==null){
            return 0;
        }
        if(k==1){
            KLevelnodes++;
        }else{
            k=k-1;
            getKLevelNodeCount(root.left,k);
            getKLevelNodeCount(root.right,k);
        }
        return KLevelnodes;
    }

main中调用

System.out.println("请输入层数:");
Scanner scan=new Scanner(System.in);
int k= scan.nextInt();
System.out.println("第"+k+"层的节点个数是:"+binaryTree.getKLevelNodeCount(root,k));

法2:子问题:整层的节点=左子树的叶子节点+右子树的叶子节点

//左子树的节点+右子树的节点
    public int getKLevelnodes2(TreeNode root,int k){
        if(root==null){
            return 0;
        }
        if(k==1){
            return 1;
        }else{
            k=k-1;
            return getKLevelnodes2(root.left,k)+getKLevelnodes2(root.right,k);
        }
    }
System.out.println("请输入层数:");
Scanner scan=new Scanner(System.in);
int k= scan.nextInt();
System.out.println("第"+k+"层的节点个数是:"+binaryTree.getKLevelnodes2(root,k));

5.求第K层的节点个数

  • 空树 = 0
  • 叶子节点 = max (0,0)+1 = 1
  • 非叶子 = 左右最高那个 + 1
//获取二叉树的高度
    public int nodeHeight(TreeNode root){
        if(root==null){
            return 0;
        }
        int leftHeight=nodeHeight(root.left);
        int rightHeight=nodeHeight(root.right);
        return Math.max(leftHeight,rightHeight)+1;

    }

 6.值为value的元素是否存在

  • 空节点返回 false
  • 找到返回 true
  • 否则返回 左子树查找 || 右子树查找
//检测值为value的元素是否存在
    public boolean nodeFind(TreeNode root,char value){
        if(root==null){
            return false;
        }
        if(value==root.val){
            return true;
        }
        return nodeFind(root.left,value)||nodeFind(root.right,value);
    }

  7.层序遍历

  • 队列放节点,出一个就进它左右孩子

  • 根节点先进队列
  • 取出节点 → 打印
  • 左孩子进队列 → 右孩子进队列
  • 直到队列为空

核心原理(记住这 4 点)

  1. 层序遍历 = 从上到下、从左到右,一层一层遍历
  2. 必须用队列(Queue) 辅助
  3. 先把根节点入队
  4. 循环:
    • 取出队首节点
    • 把它的左孩子、右孩子依次入队
     public void levelOrder(TreeNode root){
            if(root==null){
                return;
            }
            // 1. 创建队列
            Queue<TreeNode> queue=new LinkedList<>();
            queue.offer(root);
    
            // 2. 循环遍历
            while(!queue.isEmpty()){
                    // 取出队首节点
                    TreeNode cur=queue.poll();
                    System.out.print(cur.val+" ");
                // 左孩子不为空,入队
                    if (cur.left != null) queue.offer(cur.left);
                // 右孩子不为空,入队
                    if (cur.right != null) queue.offer(cur.right);
    
               
            }
    
        }

     8.判断一棵树是否是完全二叉树

    8.1 什么是完全二叉树?

    一句话记住:除了最后一层,其他层都是满的;最后一层的节点,都靠左排列。

    8.2 判断核心规则(层序遍历)

    1. 用队列一层一层遍历节点
    2. 遇到第一个 null 之后不能再出现非 null 节点
    3. 如果满足 → 是完全二叉树不满足 → 不是
    //判断是否是完全二叉树
        //用队列一层一层遍历节点
        //遇到第一个 null 之后,不能再出现非 null 节点
        //如果满足 → 是完全二叉树不满足 → 不是
        public boolean isCompleteBinaryTree(TreeNode root){
            if(root==null){
                return true;
                //空树 = 完全二叉树
            }
            // 1. 创建队列
            Queue<TreeNode> queue=new LinkedList<>();
            queue.offer(root);
            boolean flag=false; // 标记:是否已经遇到过 null
            // 2. 循环遍历
            while(!queue.isEmpty()){
    
                // 取出队首节点
                TreeNode cur=queue.poll();
                if(cur==null){
                    flag=true;//已经遇到了null
                }else{
                    if(flag)
                    //已经遇到了null 但又遇到了非空
                    return false;
    
                    // ✅ 关键:只有 cur 不是 null,才把左右孩子入队(包括 null)
                    queue.offer(cur.left);
                    queue.offer(cur.right);
    
                    //1. 只要 cur == null
                    //绝对不能访问 cur.left/cur.right
                    //2. 入队必须写在 else 里面
                    //只有 cur 不是 null,才把左右孩子丢进队列!
                }
    
    
            }
            return true;
        }

    总结

    以上就是今天要讲的内容,本文简单记录了java数据结构,仅作为一份简单的笔记使用,大家根据注释理解,您的点赞关注收藏就是对小编最大的鼓励!

    您可能感兴趣的与本文相关的镜像

    Python3.8

    Python3.8

    Conda
    Python

    Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包

    打赏作者

    Yvonne爱编码

    你的鼓励将是我创作的最大动力

    ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
    扫码支付:¥1
    获取中
    扫码支付

    您的余额不足,请更换扫码支付或充值

    打赏作者

    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值