Day9 25/2/22 SAT

【一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解(马士兵)】https://www.bilibili.com/video/BV13g41157hK?p=4\&vd_source=04ee94ad3f2168d7d5252c857a2bf358

目录

5、二叉树

[5.0 二叉树节点结构](#5.0 二叉树节点结构)

[5.1 前序/中序/后序遍历 & 递归/非递归实现](#5.1 前序/中序/后序遍历 & 递归/非递归实现)

[5.1.1 前序/中序/后序遍历区分](#5.1.1 前序/中序/后序遍历区分)

[5.1.2 递归实现](#5.1.2 递归实现)

[5.1.3 非递归实现](#5.1.3 非递归实现)

[5.2 直观地打印一棵二叉树](#5.2 直观地打印一棵二叉树)

[5.3 二叉树的宽度优先遍历](#5.3 二叉树的宽度优先遍历)

[5.4 二叉树类型判断](#5.4 二叉树类型判断)

二叉搜索树

完全二叉树

真二叉树

满二叉树

平衡二叉树


笔记:

5、二叉树

5.0 二叉树节点结构

java 复制代码
class Node<V>{
    V calue;
    Node left;
    Node right;
}

5.1 前序/中序/后序遍历 & 递归/非递归实现

5.1.1 前序/中序/后序遍历区分

在二叉树中,遍历的顺序指的是访问节点的顺序:

前序遍历(Pre-order Traversal):根节点 -> 左子树 -> 右子树。

中序遍历(In-order Traversal):左子树 -> 根节点 -> 右子树。

后序遍历(Post-order Traversal):左子树 -> 右子树 -> 根节点。

主要区别在于根节点的访问时机:

前序遍历最先访问根节点。

中序遍历,根节点在左右子树都访问完成后才被访问。

后序遍历最后访问根节点。

5.1.2 递归实现

java 复制代码
class Node<V>{
    V calue;
    Node left;
    Node right;
}

// 前序遍历
public void preOrder(Node root) {
    if (root == null) return;
    System.out.print(root.val + " ");  // 先访问根节点
    preOrder(root.left);               // 再遍历左子树
    preOrder(root.right);              // 最后遍历右子树
}

// 中序遍历
public void inOrder(Node root) {
    if (root == null) return;
    inOrder(root.left);                // 先遍历左子树
    System.out.print(root.val + " ");  // 再访问根节点
    inOrder(root.right);               // 最后遍历右子树
}

//后序遍历
public void postOrder(Node root) {
    if (root == null) return;
    postOrder(root.left);              // 先遍历左子树
    postOrder(root.right);             // 再遍历右子树
    System.out.print(root.val + " ");  // 最后访问根节点
}

5.1.3 非递归实现

任何递归函数都可以改成非递归函数,相当于不让系统自动压入栈,而是自己手动压入栈。栈是先进后出的。

前序遍历中,遍历顺序为"头左右"(头节点、左子节点、右子节点),操作:

step 1. 从栈中弹出一个节点N

step 2. 找到它的左、右子节点

step 3. 先压入栈右子节点,再压入左子节点(这样先弹出左子节点,再弹出右子节点)

java 复制代码
public static void preorder(Node node){
    if(node != null){
        Stack<Node> stack = new Stack<Node>();
        stack.add(node);

        while( !stack.isEmpty() ){
            node = stack.pop();
            System.out.print(node.value + " ");
            if( node.right != null)stack.push(node.right);
            if( node.left != null)stack.push(node.left);
        }
    }
}

中序遍历中,遍历顺序为"左头右"(左子节点、头节点、右子节点),操作:

java 复制代码
public static void inorder(Node node){
    if(node != null){
        Stack<Node> stack = new Stack<Node>();
        while( !stack.isEmpty() || node != null ){
            if( node != null){
                stack.push(node);
                node = node.left;
            }else{
                node = stack.pop();
                System.out.print(node.value + " ");
                node = node.right;
            }
        }
    }
}

后序遍历中,遍历顺序为"左右头"(左子节点、右子节点、头节点),操作:

java 复制代码
public static void postorder(Node node){
    if(node != null){
        Stack<Node> s1 = new Stack<Node>();
        Stack<Node> s2 = new Stack<Node>();
        s1.push(node);
        
        while( !s1.isEmpty() ){
            node = s1.pop();
            s2.push(node);
            if( node.left!= null)s1.push(node.left);
            if( node.right!= null)s1.push(node.right);
        }
        while( !s2.isEmpty() ) System.out.print(s2.pop().value + " ");
    }
}

5.2 直观地打印一棵二叉树

java 复制代码
class BinaryTreePrinter {
    // 打印二叉树的结构
    static void printTree(TreeNode root) {
        printTree(root, "", true);
    }

    // 辅助方法:递归打印每层节点
    private static void printTree(TreeNode node, String indent, boolean last) {
        if (node != null) {
            System.out.println(indent + (last ? "└── " : "├── ") + node.val);
            indent += last ? "    " : "│   ";
            printTree(node.left, indent, false);  // 打印左子树
            printTree(node.right, indent, true);  // 打印右子树
        }
    }

    public static void main(String[] args) {
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(5);
        root.right.left = new TreeNode(6);
        root.right.right = new TreeNode(7);
        
        printTree(root);
    }
}

5.3 二叉树的宽度优先遍历

常见题目:求一颗二叉树的宽度,也就是树的每层最多存在了几个节点。

可以采用队列Queue进行辅助,队列的特性是先进先出。遍历完一层后要遍历下一层的节点时,每次弹出一个节点,再把它的左右子节点推进队列。

java 复制代码
public static void broadReversal(Node node) {
        if (node == null) return;

        Queue<Node> queue = new LinkedList<>();
        queue.add(node);

        int maxWidth = 0;

        // 广度优先遍历
        while (!queue.isEmpty()) {
            // 获取当前层的节点数
            int levelSize = queue.size();
            maxWidth = Math.max(maxWidth, levelSize); // 更新最大宽度

            // 遍历当前层
            for (int i = 0; i < levelSize; i++) {
                Node current = queue.poll();
                System.out.print(current.value + " "); // 输出当前节点的值

                // 将左右子节点加入队列
                if (current.left != null) queue.add(current.left);
                if (current.right != null) queue.add(current.right);
            }
            System.out.println(); // 换行,表示一层的结束
        }

        System.out.println("Maximum width of the binary tree is: " + maxWidth);
    }

5.4 二叉树类型判断

与一个节点直接连接的子节点数,也叫"度数"。

度数为0即没有左右节点,度数为1则只有左节点或右节点,度数为2

二叉搜索树

是一类二叉树,左子树的key都小于当前节点的key、右子树的key都大于当前节点的key

完全二叉树

是一类二叉树,叶子节点只会出现在最后两层(最后一层可能不是满的),且最后一层的叶子节点都靠左对齐 特点:完全二叉树从root到倒数第二层是一棵满二叉树; 度数为1的节点只有左子树;

真二叉树

是一类二叉树,所有节点的度要么为0要么为2。

满二叉树

是一类二叉树,每一层都是满的,而且叶子节点都在同一层上。

平衡二叉树

每个节点都有一个平衡因子(balance factor)来确保树的高度始终保持在一个较小的范围内,从而保证查询、插入和删除操作的时间复杂度始终为O(logn)

性质:所有操作的时间复杂度都为O(logn)

①左右子节点的高度差的绝对值不超过1(the children of a node can differ by at most 1)

②左小右大

③height-balance 高度是平衡的

应用场景:适用于需要严格保证操作时间的场景(比如数据库搜索)

相关推荐
掘金安东尼2 小时前
Amazon Lambda + API Gateway 实战,无服务器架构入门
算法·架构
码流之上2 小时前
【一看就会一写就废 指间算法】设计电子表格 —— 哈希表、字符串处理
javascript·算法
快手技术4 小时前
快手提出端到端生成式搜索框架 OneSearch,让搜索“一步到位”!
算法
CoovallyAIHub1 天前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
NAGNIP1 天前
Serverless 架构下的大模型框架落地实践
算法·架构
moonlifesudo1 天前
半开区间和开区间的两个二分模版
算法
moonlifesudo1 天前
300:最长递增子序列
算法
CoovallyAIHub1 天前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
CoovallyAIHub1 天前
英伟达ViPE重磅发布!解决3D感知难题,SLAM+深度学习完美融合(附带数据集下载地址)
深度学习·算法·计算机视觉
聚客AI2 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm