Java树形结构


首先为什么要使用tree结构呢?树结合了两种数据结构的优点,一种是有序数组,树在查找数据项的速度和有序数组查找一样快;另一种是链表,树在插入数据和删除数据项的速度和链表一样。

二叉树

二叉树的概念

树有很多种,每个节点最多只能有2个子节点的形式称为二叉树,二叉树的子节点分为 左子节点和右子节点。

  1. 满二叉树定义:如果该二叉树的所有叶子节点都在最后一层,则称为满二叉树。
  2. 完全二叉树 定义:如果该二叉树的所有叶子节点都在最后一层或者倒数第二层,而且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,则称为完全二叉树。

二叉树的特点

  • 每个节点最多有2个子树的有序数。
  • 左子结点的关键值必须小于父节点。右子节点的关键值必须大于父节点。

二叉树的前序、中序、后续遍历

  • 前序遍历 先输出父节点,在遍历左子树和右子树
  • 中序遍历 先遍历左子树,在输出父节点,在遍历右子树
  • 后续遍历 先遍历左子树,在遍历右子树,最后输出父节点

小结:看输出父节点的顺序,就确定是前序、中序还是后序。

平衡二叉树(AVL树)

平衡二叉树在符合二叉树的条件下,还满足额外的平衡条件,

  1. 平衡条件 对于树中的任意节点,其左子树和右子树的高度最多相差1
  2. 高度平衡 平衡二叉树在插入、删除节点后,能够通过调整树的结构(比如通过旋转操作)来保持树的高度大致平衡,从而保证了在最坏的情况下,查找,插入,删除等操作的时间复杂度接近0(n),其中n是树种节点的数量。

常见的平衡二叉树实现包括AVL树(Adelson-Velsky and Landis Tree)和红黑树(Red-Black Tree)等。这些树结构在动态数据结构中特别有用,因为在数据频繁变动时,通过自我调整能够维持高效的查询性能。

B-tree

阶数

  1. 什么是树的阶数?
    树的阶数表示一个节点最多能有多少个子节点。也就是每个节点上最多的键值个数,比如二叉树的阶数就是2.

  2. 描述一颗b tree时,需要指定他的阶数,阶数表示此b tree的节点(除根节点外) 最多有多少个 孩子节点(子树),一般用字母M表示。
    如:M阶的b tree,以子树讨论:

  • 上限: 每个节点最多有M个子树。
  • 下限:
    根节点:至少2个子树
    非根节点:至少有 ⌈M /2⌉ 个 子树 。( 注意:M /2 向上取整,如 5/2等于3 )

所以也称 M 阶的 B树 为 ( ⌈M /2⌉ , M ) 树 ,即超级节点(除根节点)的子树数的上下限 。
另外,关键字(码)的个数 = 节点子树数 - 1 。

定义

  • BTree意思是多路平衡查找树,它是一种数据结构。
    MySQL的InnoDB和MyISAM存储引擎,都是使用它来存储索引。BTree可细分为B-Tree和B+Tree,B+Tree是B-Tree的升级版。MySQL的InnoDB和MyISAM存储引擎使用的是B+Tree。
  • 相比普通的二叉平衡树,特点是更加“矮胖”,提高了搜索效率,降低了数据库IO的次数。

为了描述b-tree,首先定义一条记录为一个二元数组[key,data],key为记录的键值,对应表中的主键,data为一行记录中除主键外的数据。对于不同的记录,key值互不相同。如下图中的紫色部分就是key,橙色部分就是一行数据,绿色部分就是指针。

在这里插入图片描述

  • P为指针,每个内部节点包含若个key以及与之数量相同加上1的指针。
    键是有序列的,每个键与其左侧指针和右侧指针一起构成了一个区间。
    这些指针指向的就是子节点在屋里存储空间的地址,可以是磁盘块的地址、内存地址或者其他形式的引用地址。
    当访问某个子节点时,btree 通过内部节点的指针快速定位到相应的子节点所在的存储位置。从而实现高效的检索和更新操作。

一颗m阶的b-tree有如下特征:

  1. 每个节点最多有m个子节点,如上图是一个3阶的树,那最多有3个子节点。
  2. 除根节点外,其他每个分支节点至少有 m/2 颗子树。
  3. 根节点至少有两颗子树。(除非B-tree只包含一个节点)
  4. 所有叶节点在同一层上,B树的叶节点可以看成一种外部节点,不包含其他关键字信息。
  5. 指针存储的是子节点所在磁盘块的位置。
  6. key(1,2,3,4)为关键字,且关键字按照升序排序。

B+tree

参考地址:https://blog.csdn.net/qq_21378941/article/details/127897414

从btree的结构图可以看到,每个节点中不仅包含数据的key值,还有data值,而每一个页的存储空间是有限的,一般为16k,如果data数据较大时将会导致每个节点(即一个页)能存储的key数量很小。当存储的数据量很大时同样 会导致btree的深度较大,增加查询的磁盘io次数,进而影响查询效率。
为了解决这个问题,在btree基础上就产生了一种新的数据结构B+tree。
在这里插入图片描述

一颗m阶的b+tree的特性和m阶的btree基本相同,除了一下几点:

  1. 非叶子节点上只存储key值信息,而不存储data信息。
  2. 非叶子节点的 子树指针 与 关键字 个数相同。
  3. 非叶子节点的子树指针 P[i] , 指向关键字值属于 [K[i], K[i+1]) 的子树( B- 树是开区间)
  4. 所有关键字都会出现在叶子节点的链表中(稠密索引),且链表中的关键字恰好是有序的。如上图所示的升序。

btree b+tree区别

  1. 节点的不同
  • B-Tree 的子节点都是相同的。无论叶子节点还是非叶子结点,上面存储的数据都是索引 + 数据;
  • B+Tree 的叶子节点和非叶子结点存储内容不同,非叶子节点只存储索引信息,叶子节点之存储具体数据信息;
  1. 索引与数据分离
  • B-Tree 各节点的索引和数据是放在一起的;
  • B+Tree 的索引和数据分离开来,所以非叶子结点只占用了很小一部分的空间,大部分空间被存储数据信息的叶子节点占据
  1. 数据结构
  • B-Tree 是一个比较单纯的树结构;所以 B-Tree 结构的同一个父节点的相邻叶子节点,在物理上很可能是相距很远的;
  • B+Tree 在 B-Tree 的基础树结构之上,在叶子节点之间添加了指针连接,使所有叶子节点形成了一个链表结构,提升了叶子节点的顺序读取效率。
  1. 在btree中,越靠近根节点的记录查找时间越快,只要找到关键字即可确定记录的存在;而b+tree中每个记录的查找时间基本是一样的,都需要从根节点走到叶子节点,而且在叶子节点中还要再比较关键字。

b+tree优势

  1. B+Tree 相对于 B-Tree 多了叶子节点的链表结构,所以在顺序读取的效率上是远高于 B-Tree 的;这在磁盘预读原理之下,成为十分重要的优势;
  2. 因为每个节点不存数据区(内存地址)了,所有每个节点的度可以更多,这样树的高度可以变矮很多,更利于查找
  3. 数据区都在叶子节点存着,一条链表,在排序时更有优势
  4. b+树的节点变换时,是分裂形式而不是b树的左旋转(右旋转)形式,效率高
  5. 但是B+树有个缺点,就是不论查什么数据都必须要遍历到叶子节点才可以拿到真实的数据地址

红黑树

什么是红黑树

红黑树是一种平衡二叉搜索树,其节点由红-黑两种颜色组成。

红黑树的特征

  1. 根节点为黑色
  2. 节点只有红黑两种颜色
  3. 红节点的两个子节点一定为黑色。
  4. 黑节点高度平衡
  5. 叶子节点为黑色
  6. 黑节点一定有2个子节点
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java树形结构的封装可以通过递归思路进行构建。可以定义一个树节点数据类,其中包含节点的ID、父节点ID、节点名称以及子节点列表等信息。可以使用Lombok库来简化代码,省略实体类的set()和get()方法。引入Lombok的Jar包后,可以使用@Data注解来自动生成这些方法。\[1\] 在树节点数据类中,可以定义入参和出参,使用泛型来处理通用的基本信息。可以使用@Builder注解来生成构建器方法,方便创建对象。\[2\] 另外,可以定义一个TreeNode类来表示每个节点的信息,包括节点ID、父节点ID、节点名称以及子节点列表。可以使用@Getter和@Setter注解来自动生成get和set方法。\[3\] 通过递归的方式,可以根据给定的数据构建树形结构。可以根据节点的父节点ID来递归地将节点添加到对应的父节点的子节点列表中,最终形成完整的树形结构。 这样封装的树形结构可以方便地返回给前端,并以下拉菜单等形式进行展示。 #### 引用[.reference_title] - *1* *3* [Java后端递归构建树形结构](https://blog.csdn.net/a18505947362/article/details/122458089)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [java代码封装的树型通用结构](https://blog.csdn.net/weixin_41905047/article/details/128889084)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值