二叉树相关知识

news2024/10/2 12:40:40

目录

一.基础

1. 定义

2. 二叉树的特点

3. 二叉树的类型

(1) 满二叉树:

(2) 完全二叉树:

(3) 斜二叉树:

 (4) 二叉搜索树(Binary Search Tree,BST)

(5)平衡二叉搜索树(Balanced Binary Search Tree)

4. 二叉树的遍历

(1)深度优先遍历

(2)广度优先遍历

5. 二叉树的存储结构

• 顺序存储结构

• 链式存储结构

6. 二叉树的性质

7. 二叉树的构建

5. 二叉树的应用

二.拓展

1. 二叉树的操作及算法复杂度

2. 二叉树的平衡问题

3.Java中的二叉树实现

(1). 定义二叉树节点类

(2). 构建二叉树

(3). 二叉树的遍历实现

• 前序遍历:

• 中序遍历:

• 后序遍历:

(4). 其他操作


一.基础

1. 定义

二叉树是一种树形结构,它是每个节点最多有两个子树的树结构,通常子树被称作“左子树”和“右子树”。

2. 二叉树的特点

a.递归性:二叉树的定义是递归的,即二叉树可以用其自身来定义。一个二叉树要么为空,要么由一个根节点、一棵左子树和一棵右子树组成,左子树和右子树也都是二叉树。

b.节点结构:二叉树中的每个节点包含数据元素以及指向左子树和右子树的指针(如果存在的话)。

3. 二叉树的类型

(1) 满二叉树:

如果一棵二叉树的所有叶节点都在同一层,并且每个非叶节点都有两个子节点,那么这棵二叉树就是满二叉树。例如:

(2) 完全二叉树:

1. 定义

• 完全二叉树是一种特殊的二叉树。设二叉树的深度为h(根节点所在层为第1层)。

• 对于完全二叉树,除了第h层外,其它各层的节点数都达到最大个数,即第i层有(2的i-1次方)个节点。

• 在第h层上的节点都集中在最左边,这意味着第h层节点是从左向右连续存在的。

2. 示例

• 例如,下面这棵二叉树就是完全二叉树:

      1
    /   \
   2     3
  / \   /
 4   5 6

• 而下面这棵二叉树不是完全二叉树:

      1
    /   \
   2     3
    \     \
     4     5

• 因为在第二层中,节点2的右子树节点4的位置不符合完全二叉树的要求(完全二叉树要求节点是按层序从左到右依次排列的)。

(3) 斜二叉树:

是一种特殊的二叉树,所有节点都只有左子树或者所有节点都只有右子树。例如,所有节点都只有左子树的斜二叉树:

1
 \
  2
   \
    3
     \
      4

 (4) 二叉搜索树(Binary Search Tree,BST)

(a)定义

二叉搜索树是一种特殊的二叉树,它满足以下性质:对于树中的任意一个节点,其左子树中的所有节点的值都小于该节点的值,其右子树中的所有节点的值都大于该节点的值。

(b)节点插入操作

插入一个新节点时,首先从根节点开始比较。如果新节点的值小于当前节点的值,则向左子树方向继续比较;如果新节点的值大于当前节点的值,则向右子树方向继续比较。直到找到合适的空位置插入新节点。

(c)节点查找操作

查找一个值时,也是从根节点开始。如果要查找的值等于当前节点的值,则查找成功;如果要查找的值小于当前节点的值,则在左子树中继续查找;如果要查找的值大于当前节点的值,则在右子树中继续查找。如果最终未找到匹配的节点,则查找失败。

(d)节点删除操作

情况较为复杂。如果要删除的节点是叶节点(没有子节点),直接删除即可;如果要删除的节点只有一个子节点,那么将这个子节点取代被删除节点的位置;如果要删除的节点有两个子节点,通常的做法是用该节点右子树中的最小值(即右子树中最左边的节点)或者左子树中的最大值(即左子树中最右边的节点)来替换被删除的节点,然后再删除用于替换的那个节点。

(e)时间复杂度

在理想情况下,二叉搜索树的高度为 O(logn)(n为树中节点个数),此时查找、插入和删除操作的时间复杂度都是 O(logn)。但在最坏情况下,例如当二叉搜索树退化为斜二叉树(所有节点都只有左子树或者所有节点都只有右子树)时,树的高度为O(n),这些操作的时间复杂度也会退化为O(n)。

(5)平衡二叉搜索树(Balanced Binary Search Tree)

(a)定义

平衡二叉搜索树是一种特殊的二叉搜索树,它在满足二叉搜索树性质的基础上,还保证树的高度是相对平衡的。不同类型的平衡二叉搜索树有不同的平衡定义。

(b)目的

为了克服二叉搜索树在最坏情况下时间复杂度退化为O(n)的问题,平衡二叉搜索树通过自动调整树的结构来保持树的高度在 O(logn)范围内,从而保证查找、插入和删除操作的时间复杂度始终为 O(logn)。

(c)常见类型

• AVL树

平衡因子:AVL树中每个节点都有一个平衡因子,定义为左子树高度减去右子树高度的值,这个值只能是0、1或者-1。

调整操作:当插入或删除节点导致平衡因子超出这个范围时,就需要通过旋转操作(左旋、右旋、先左旋后右旋、先右旋后左旋)来重新平衡树。例如,在插入一个节点后,如果某个节点的平衡因子变为2或-2,就需要进行调整。

• 红黑树

节点颜色属性:红黑树的每个节点除了有数据域、左指针域、右指针域外,还有一个颜色属性,节点颜色可以是红色或者黑色。

红黑性质:

根节点是黑色的。

每个叶节点(空节点)是黑色的。

如果一个节点是红色的,则它的两个子节点都是黑色的(从每个叶子到根的所有路径上不能有两个连续的红色节点)。

从任一节点到其每个叶节点的所有路径上包含相同数目的黑色节点。

调整操作:当插入或删除节点破坏了红黑性质时,需要通过变色和旋转操作来恢复红黑性质,从而保持树的平衡。

4. 二叉树的遍历

(1)深度优先遍历

• 前序遍历:先访问根节点,然后前序遍历左子树,再前序遍历右子树。例如对于二叉树:

      1
    /   \
   2     3
  / \   / \
 4   5 6   7

前序遍历的结果是:1、2、4、5、3、6、7。

• 中序遍历:先中序遍历左子树,然后访问根节点,再中序遍历右子树。上述二叉树的中序遍历结果是:4、2、5、1、6、3、7。

• 后序遍历:先后序遍历左子树,然后后序遍历右子树,最后访问根节点。该二叉树的后序遍历结果是:4、5、2、6、7、3、1。

(2)广度优先遍历

• 层序遍历:按层次顺序,从根节点开始,逐层向下遍历二叉树,同一层的节点按照从左到右的顺序访问。上述二叉树的层序遍历结果是:1、2、3、4、5、6、7。

5. 二叉树的存储结构

• 顺序存储结构

对于完全二叉树,可以采用顺序存储结构。将二叉树的节点按照从上到下、从左到右的顺序依次存储在数组中。

节点在数组中的下标具有一定的规律,设根节点的下标为0,如果某个节点的下标为i,那么它的左子节点的下标为2i + 1,右子节点的下标为2i+2。

但是这种存储方式对于非完全二叉树会造成空间浪费,因为要保证逻辑上二叉树的结构,可能需要用空节点来填补数组中的某些位置。

• 链式存储结构

二叉链表:每个节点包含三个域,数据域、左指针域和右指针域。左指针指向该节点的左子节点,右指针指向该节点的右子节点。这种结构简单灵活,是二叉树最常用的存储方式。

三叉链表:在二叉链表的基础上增加一个父指针域,用于指向该节点的父节点。这种结构在某些需要回溯到父节点的操作中比较方便,例如在计算二叉树的高度、求最近公共祖先等操作中。

6. 二叉树的性质

• 二叉树第i层上的最大节点数为 (2的i-1次方(i>=1))。

• 深度为k的二叉树的最大节点数为 (2的k次方-1(k>=1))。

• 对任何一棵二叉树,如果其叶节点个数为n0,度为2的节点个数为n2,则n0 = n2 + 1。可以通过分析二叉树中节点的度数关系(总度数+1 = 节点总数)来推导这个性质。

7. 二叉树的构建

可以根据给定的遍历序列来构建二叉树。但是需要注意的是,仅通过一种遍历序列(如中序遍历、前序遍历或后序遍历中的一种)不能唯一确定一棵二叉树。但是如果已知中序遍历序列和前序遍历序列,或者中序遍历序列和后序遍历序列,则可以唯一确定一棵二叉树。

• 例如,已知前序遍历序列和中序遍历序列构建二叉树的过程:

• 首先,前序遍历的第一个节点为根节点。

• 在中序遍历中,将序列分为两部分,左边是左子树的中序遍历序列,右边是右子树的中序遍历序列。

• 在前序遍历中,是左子树的前序遍历序列,是右子树的前序遍历序列。

• 然后分别对左子树和右子树递归地进行构建。

5. 二叉树的应用

在数据结构和算法中广泛应用,例如用于构建二叉搜索树(BST),以实现高效的查找、插入和删除操作;在表达式树中表示算术表达式;在哈夫曼树中用于数据压缩等。

二.拓展

1. 二叉树的操作及算法复杂度

(1) 插入节点

在二叉链表存储的二叉树中插入节点操作相对复杂,需要考虑插入的位置(作为叶节点插入或者替换某个节点等情况)。如果插入节点的操作是作为叶节点插入到二叉搜索树(一种特殊的二叉树)中,平均时间复杂度为O(logn)(为树中节点个数),最坏情况(树退化为斜二叉树)为O(n)。

(2) 删除节点

同样在二叉搜索树中,删除节点根据节点的度数(0度、1度或2度)不同有不同的处理方式。平均时间复杂度为O(logn),最坏情况为O(n)。

(3) 查找节点

在二叉搜索树中,根据节点的值进行查找。平均时间复杂度为O(logn),最坏情况为O(n)。如果是普通二叉树,查找操作可能需要遍历整棵树,时间复杂度为O(n)。

2. 二叉树的平衡问题

• 在二叉搜索树中,如果插入和删除操作不当,可能会导致树变得不平衡,例如形成斜二叉树,这会使查找、插入和删除操作的时间复杂度退化为O(n)。

• 为了解决这个问题,有多种平衡二叉树的算法,如AVL树和红黑树。AVL树通过调整节点的平衡因子(左子树高度与右子树高度之差),在插入和删除节点时进行旋转操作(左旋、右旋、先左旋后右旋、先右旋后左旋)来保持树的平衡,使得树的高度始终保持在O(logn),从而保证操作的时间复杂度为O(logn)。红黑树则通过定义节点的颜色(红色或黑色),并在插入和删除节点时通过变色和旋转操作来保持树的平衡。

3.Java中的二叉树实现

(1). 定义二叉树节点类

• 首先,需要定义二叉树的节点类,节点类包含节点的值以及指向左子节点和右子节点的引用。• 以下是一个简单的Java代码示例:

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

(2). 构建二叉树

• 可以通过手动创建节点并连接它们来构建二叉树。例如,构建一个简单的二叉树:

public class BinaryTreeExample {
    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);
    }
}

(3). 二叉树的遍历实现

• 前序遍历:

• 递归实现:

public static void preorderTraversal(TreeNode root) {
        if (root!= null) {
            System.out.print(root.val + " ");
            preorderTraversal(root.left);
            preorderTraversal(root.right);
        }
    }

• 非递归实现(使用栈):

    public static void preorderTraversalNonRecursive(TreeNode root) {
        if (root == null) {
            return;
        }
        java.util.Stack<TreeNode> stack = new java.util.Stack<>();
        stack.push(root);
        while (!stack.empty()) {
            TreeNode node = stack.pop();
            System.out.print(node.val + " ");
            if (node.right!= null) {
                stack.push(node.right);
            }
            if (node.left!= null) {
                stack.push(node.left);
            }
        }
    }
• 中序遍历:

• 递归实现:

    public static void inorderTraversal(TreeNode root) {
        if (root!= null) {
            inorderTraversal(root.left);
            System.out.print(root.val + " ");
            inorderTraversal(root.right);
        }
    }

• 非递归实现(使用栈):

    public static void inorderTraversalNonRecursive(TreeNode root) {
        if (root == null) {
            return;
        }
        java.util.Stack<TreeNode> stack = new java.util.Stack<>();
        TreeNode current = root;
        while (current!= null ||!stack.empty()) {
            while (current!= null) {
                stack.push(current);
                current = current.left;
            }
            current = stack.pop();
            System.out.print(current.val + " ");
            current = current.right;
        }
    }
• 后序遍历:

• 递归实现:

    public static void postorderTraversal(TreeNode root) {
        if (root!= null) {
            postorderTraversal(root.left);
            postorderTraversal(root.right);
            System.out.print(root.val + " ");
        }
    }

• 非递归实现(使用栈和一个额外的变量记录上一次访问的节点):

    public static void postorderTraversalNonRecursive(TreeNode root) {
        if (root == null) {
            return;
        }
        java.util.Stack<TreeNode> stack = new java.util.Stack<>();
        TreeNode lastVisited = null;
        while (root!= null ||!stack.empty()) {
            while (root!= null) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            // 如果右子节点为空或者已经访问过,则访问该节点
            if (root.right == null || root.right == lastVisited) {
                System.out.print(root.val + " ");
                lastVisited = root;
                root = null;
            } else {
                stack.push(root);
                root = root.right;
            }
        }
    }

(4). 其他操作

• 例如计算二叉树的高度:

    public static int getHeight(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftHeight = getHeight(root.left);
        int rightHeight = getHeight(root.right);
        return Math.max(leftHeight, rightHeight)+1;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2184421.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS | 面试题:你知道几种移动端适配方案?

目录 一、自适应和响应式 二、为什么要做移动端适配&#xff1f; 三、当前流行的几种适配方案 (1) 方案一&#xff1a;百分比设置&#xff08;不推荐&#xff09; (2) 方案二&#xff1a;rem 动态设置 font-size px 与 rem 的单位换算 手动换算 less/scss函数 webpac…

存储主动防御,为什么Gartner技术曲线尤为重视?

【科技明说 &#xff5c; 科技热点关注】 近来&#xff0c;从Gartner发布的2024年存储技术成熟曲线&#xff08;Hype Cycle for Storage Technologies ,2024&#xff09;的相关报告看出&#xff0c;到2028年&#xff0c;所有存储产品都将融入专注于数据主动防御的网络存储功能&…

PyCharm 社区版(2024.2.3)安装、配置、创建项目

PyCharm 社区版&#xff08;2024.2.3&#xff09;安装、配置、创建项目 本文目录&#xff1a; 零、时光宝盒 一、PyCharm简介 二、PyCharm特点和功能 三、PyCharm的安装 3.1、PyCharm的安装条件 3.2、下载PyCharm 3.3、安装PyCharm 四、配置PyCharm 4.1、PyCharm的汉化…

基础算法--递归算法【难点、重点】

今天我们即将要开始讲解算法中第一块儿难啃地骨头--递归了&#xff0c;相信有不少小伙伴都因递归而迷惑过&#xff0c;本文就来给大家详细的讲解一下递归到底是什么东西。让你也能瞬间将他打回原形。 递归的理解 在学习递归之前&#xff0c;我们先理解递归。什么是递归呢&…

【论文阅读】MRFS: Mutually Reinforcing Image Fusion and Segmentation(CVPR2024)

MRFS: Mutually Reinforcing Image Fusion and Segmentation&#xff08;CVPR2024&#xff09; 背景和动机 1.特征中和缺点和低光信息丢失。 红外和可见光图像通常在强度和梯度分布方面表现出显着差异。在这种情况下&#xff0c;传统的固定比例的无监督损失可能会削弱有价值…

NASA:ATLAS/ICESat-2 L3B 每日和每月网格极地海面高度异常 V003

目录 简介 摘要 代码 引用 网址推荐 0代码在线构建地图应用 机器学习 ATLAS/ICESat-2 L3B Daily and Monthly Gridded Polar Sea Surface Height Anomaly V003 ATLAS/ICESat-2 L3B 每日和每月网格极地海面高度异常 V003 简介 ATLAS/ICESat-2 L3B Daily and Monthly G…

Gamisodes在Sui上推出动画版《神探加杰特》

没错&#xff0c;大家喜爱的卡通角色《神探加杰特》将以全新可玩形式登陆Sui区块链&#xff0c;这要归功于Gamisodes。通过其独特技术&#xff0c;Gamisodes正将《神探加杰特》重新制作为互动式剧集&#xff0c;并在Sui上重现这一经典系列。 Gamisodes平台推出了真正互动的《神…

高精度四则运算专题

高精度X高精度加法、减法、乘法 高精度X普通精度 乘法 高精度X普通精度 除法 目录 高精度X高精度 加法 题目 要点 代码 高精度X高精度 减法 题目 要点 代码 高精度X普通精度 乘法 题目 要点 代码 高精度X高精度 乘法 要点 代码 高精度X普通精度 除法 题目 要点 代…

GESP C++四级样题卷

&#xff08;满分&#xff1a;100 分 考试时间&#xff1a;90 分钟&#xff09; PDF试卷及答案回复:GESPC20234 一、单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09; 1.在 C中&#xff0c;指针变量的大小&#xff08;单位&#xff1a;字节&#xff09;是&#…

计算机网络-系分(5)

目录 计算机网络 DNS解析 DHCP动态主机配置协议 网络规划与设计 层次化网络设计 网络冗余设计 综合布线系统 1. 双栈技术 2. 隧道技术 3. 协议转换技术 其他网络技术 DAS&#xff08;Direct Attached Storage&#xff0c;直连存储&#xff09; NAS&#xff08;Net…

《Windows PE》3.2.4节表

节表由多个节表项&#xff08;IMAGE_SECTION_ HEADER&#xff09;组成&#xff0c;每个节表项&#xff08;40个字节&#xff09;记录了 PE中与某个特定的节有关的信息&#xff0c;如节的属性、节 的大小、在文件和内存中的起始位置等。节表中节的数量由字段IMAGE_FILE_HEADER. …

vulnhub-Matrix 1靶机

vulnhub&#xff1a;https://www.vulnhub.com/entry/matrix-1,259/ 导入靶机&#xff0c;扫描IP 靶机在192.168.81.6&#xff0c;扫描端口 存在三个端口&#xff0c;有两个都是http服务&#xff0c;访问 80端口的网页没什么信息&#xff0c;31337的网页元素里有注释 ZWNobyAi…

Raft 协议解读:简化分布式一致性

文章目录 1. 分布式系统与一致性问题1.1 什么是分布式系统1.2 一致性在分布式系统中的重要性1.3 分布式一致性挑战1.4 现有一致性协议1.5 Raft 的设计目标 2. Raft 协议的背景与介绍2.1 Raft 协议的诞生背景2.2 什么是 Raft2.3 Raft 解决的一致性问题2.4 Raft 的设计原则2.5 Pa…

Oracle 数据库安装及配置

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

PCL MLS上采样(基于法向量)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 可视化原始点云和上采样后的点云 2.1.2 MLS 上采样 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff0…

Redis-预热雪崩击穿穿透

预热雪崩穿透击穿 缓存预热 缓存雪崩 有这两种原因 redis key 永不过期or过期时间错开redis 缓存集群实现高可用 主从哨兵Redis Cluster开启redis持久化aof&#xff0c;rdb&#xff0c;尽快恢复集群 多缓存结合预防雪崩&#xff1a;本地缓存 ehcache redis 缓存服务降级&…

iPhone/iPad技巧:如何解锁锁定的 iPhone 或 iPad

“在我更新 iPhone 上的软件后&#xff0c;最近我遇到了iPhone 被锁定到所有者的消息&#xff0c;该如何解决&#xff1f;” 根据我们的研究&#xff0c;许多用户在 iOS 18 更新或恢复出厂设置后都会遇到同样的问题。只要出现问题&#xff0c;您就无法使用 iPhone 或 第 1 部分…

jenkins微服务

如果vim进去某个文件里&#xff0c;可以按键盘的向下键查阅其它部分 记得每天备份虚拟机的项目 一.在linux安装jenkins 1.上传文件 我们采用安装包的方式安装。 先用SShclient在/usr/local/下创建jenkins文件夹&#xff0c;然后向其中导入两个包 2.安装jenkins 再在控制…

「STL::queue」标准库适配器:priority_queue(优先队列)介绍|自定义比较运算(C++)

目录 概述 创建销毁 内部理解 构造析构 自定义比较 赋值重构 数据访问 内存管理 数据控制 Tips 概述 priority_queue 是一种C标准模板库STL中定义的一种序列容器&#xff0c;它允许你在运行时动态地进行堆操作。 priority_queue 可以自动管理内存&#xff0c;这意味…

使用阿里云试用资源快速部署web应用-dofaker为例

本文介绍使用阿里云的试用资源部署dofaker的方法&#xff0c;本教程主要作学习在阿里云部署web应用之用&#xff0c;部署好应用之后&#xff0c;可以在任何地点通过公网ip访问web应用。 一、创建云主机 登录阿里云账户之后&#xff0c;点击控制台&#xff1a; 点击云服务器EC…