二叉树、2-3-4树、红黑树、B Tree树、哈希表

二叉树

每个子节点只有两个节点的树

二叉查找树(二叉搜索树):就是一颗二叉树,他的左节点比父节点要小,右节点比父节点要大。他的高度决定的查找效率

在这里插入图片描述
常见操作:

1、查找(红黑树通用)

查找每个节点我们从根节点开始查找,步骤:

  • 查找值比当前值大,则搜索右子树
  • 查找值等于当前值,停止查找,返回当前节点
  • 查找值比当前值小,则搜索左子树

2、插入

要插入节点,必须先找到插入节点位置。依然是从根节点开始比较,小于根节点的话就和左子树比较,反之与右子树比较,直到左子树为空或者右子树为空,则插入到相应为空的位置

3、遍历(红黑树通用)

根据一定顺序来访问整个树,常见的有前序遍历,中序遍历(用的较多),后序遍历

  • 前序遍历:左子树-》根节点-》右子树(123 4 567)
  • 中序遍历:根节点-》左子树-》右子树 (4 213 657)
  • 后续遍历:左子树-》右子树-》根节点 (132 576 4)

4、查找最小值(红黑树通用)

沿着根节点的左子树一路查找,直到最后一个不为空的节点,该节点就是当前这个树的最小节点

5、查找最大值(红黑树通用)

沿着根节点的右子树一路查找,直到最后一个不为空的节点,该节点就是当前这个树的最大节点

6、查找前驱节点(红黑树通用):小于当前节点的最大值

7、查找后继节点(红黑树通用):大于当前节点的最小值

8、删除:本质上是找前驱或者后继节点来替代

  • 叶子节点直接删除(没有前驱或后继节点)
  • 只有一个子节点的用子节点替代(本质上就是找的前驱节点或者是后继节点,左节点就是前驱节
    点,右节点就是后继节点)
  • 有两个子节点的,需要找到替代节点(替代节点就是前驱节点或者后继节点)

删除操作和红黑树一样,只不过红黑树多了着色和旋转过程

二叉查找树存在的问题是,树在插入的时候会导致倾斜,不同的插入顺序会导致数的高度不一样,而树的高度直接影响了树的查找效率。最坏的情况所有的节点都在一条斜线上,这样树的高度为N;

基于二叉查找树存在的问题,平衡查找二叉树(Balanced BST)产生了。平衡树的插入和删除的时候,会通过旋转操作将高度保持在LogN。

其中两款具有代表性的平衡术分别为:

  1. AVL树:高度平衡树,具备二叉搜索树的全部特性,而且左右子树高度差不超过1;
  2. 红黑树

AVL树如何实现平衡的?

通过左旋或者右旋,举例(右旋):

  1. 节点5进来作为根节点,节点4进来,因为比节点5小,所以插入到根节点左子树位置

在这里插入图片描述

  1. 节点3进来,依次比较,插入到节点4的左子树位置,此时发现节点5的左右子树高度差大于1(左子树为2,右子树为0)

在这里插入图片描述

  1. 节点5进行右旋,结果如下:

在这里插入图片描述

  1. 节点2进来,依次比较,插入到节点3的左子树位置

在这里插入图片描述

  1. 节点1进来,依次比较,插入到节点2的左子树位置,此时发现节点3与节点4的左右子树高度差大于1(节点3左子树为2,右子树为0。节点4左子树为3,右子树为1)

在这里插入图片描述

  1. 节点3进行右旋,结果如下(下一层节点先右旋,因为下一层右旋完,上一层本不满足条件的可能就已经满足了):

在这里插入图片描述

如此类推!

面试题:有了AVL树为什么还要红黑树呢??

AVL树由于实现比较复杂,条件也非常的严格(左右子树高度差不超过1),而且插入和删除性能差,在实际环境下的应用不如红黑树;

2-3-4树

2-3-4树是四阶的 B树(Balance Tree),他属于一种多路查找树,它的结构有以下限制:

  • 所有叶子节点都拥有相同的深度
  • 节点只能是 2-节点(包含 1 个元素的节点,有 2 个子节点)、3-节点(包含 2 个元素的节点,有 3 个子节点)、4-节点(包含 3 个元素的节点,有 4 个子节点)之一
  • 所有节点必须至少包含1个元素
  • 元素始终保持排序顺序,整体上保持二叉查找树的性质,即父结点大于左子结点,小于右子结点。而且结点有多个元素时,每个元素必须大于它左边的和它的左子树中元素

下图是一个典型的 2-3-4树:
在这里插入图片描述
例如(10-1降序的2-3-4树如下):

  1. 节点10、9、8进来按如下排列

在这里插入图片描述

  1. 节点7进来,4个元素,那么9就需要向上裂变(中间的往上裂变出去)

在这里插入图片描述

  1. 节点6进来如下排序

在这里插入图片描述

  1. 节点5进来,4个元素,那么7就需要向上裂变

在这里插入图片描述

  1. 7与9组合在一起为3节点

在这里插入图片描述

  1. 节点4进来如下排序

在这里插入图片描述

  1. 节点3进来,4个元素,那么5就需要向上裂变,5、7、9组合为4节点

在这里插入图片描述

  1. 节点2进来,如下排序

在这里插入图片描述

  1. 节点1进来,4个元素,那么3就需要往上裂变。3裂变上去达到4个元素则7需要向上裂变!

在这里插入图片描述

2-3-4树的查询操作像普通的二叉搜索树一样,非常简单,但由于其结点元素数不确定,在一些编程语言中实现起来并不方便,实现一般使用它的等同——红黑树;

红黑树起源于2-3-4树,它的本质就是2-3-4树(一个2-3-4树可以产生多个红黑树,但一个红黑树只能对应一个2-3-4树);

为什么说红黑树是 2-3-4树的一种等同呢,这是因为 2-3-4树的每一个结点都对应红黑树的一种结构,所以每一棵 2-3-4树也都对应一棵红黑树,下图是 2-3-4树不同结点与红黑树子树的对应:

在这里插入图片描述

因此,以上的2-3-4树可以转化为红黑树:

在这里插入图片描述

红黑树

红黑树是一种结点带有颜色属性的二叉查找树,但它在二叉查找树之外,还有以下5大性质:

  1. 节点是红色或黑色。
  2. 根是黑色。
  3. 所有叶子都是黑色(叶子是NIL节点,这类节点不可以忽视,否则代码会看不懂)。
  4. 每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节
    点。)
  5. 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点(黑色平衡)。

下图就是一个典型的红黑树:
在这里插入图片描述

BTREE

BTree又叫多路平衡搜索树,一颗m叉的BTree特性如下:

  • 树中每个节点最多包含m个孩子。
  • 除根节点与叶子节点外,每个节点至少有[ceil(m/2)]个孩子(ceil表示向上取整)。
  • 若根节点不是叶子节点,则至少有两个孩子。
  • 所有的叶子节点都在同一层。
  • 每个非叶子节点由n个key与n+1个指针组成,其中[ceil(m/2)-1] <= n <= m-1

以5叉BTree为例,key的数量:公式推导[ceil(m/2)-1] <= n <= m-1。所以 2 <= n <=4 。当n>4时,中间节点分裂到父节点,两边节点分裂。

插入 C N G A H E K Q M F W L T Z D P R X Y S 数据为例,演变过程如下:

1). 插入前4个字母 C N G A

在这里插入图片描述
2). 插入H,n>4,中间元素G字母向上分裂到新的节点
在这里插入图片描述
3). 插入E,K,Q不需要分裂
在这里插入图片描述
4). 插入M,中间元素M字母向上分裂到父节点G
在这里插入图片描述
5). 插入F,W,L,T不需要分裂
在这里插入图片描述
6). 插入Z,中间元素T向上分裂到父节点中
在这里插入图片描述
7). 插入D,中间元素D向上分裂到父节点中。然后插入P,R,X,Y不需要分裂
在这里插入图片描述
8). 最后插入S,NPQR节点n>5,中间节点Q向上分裂,但分裂后父节点DGMT的n>5,中间节点M向上分裂
在这里插入图片描述
到此,该BTREE树就已经构建完成了, BTREE树 和 二叉树 相比, 查询数据的效率更高, 因为对于相同的数据量来说,BTREE的层级结构比二叉树小,因此搜索速度快。

B+TREE

B+Tree为BTree的变种,B+Tree与BTree的区别为:

1). B+Tree的叶子节点保存所有的key信息,依key大小顺序排列。

2). 所有的非叶子节点都可以看作是key的索引部分

在这里插入图片描述

哈希表

Hash函数(Hash Function):能快速将一个数值转换成哈希值(整数),所以哈希表必须保持哈希值的计算一致,如果两个哈希值是不同的,那么这两个哈希值的原始输入也是不同的;

那如果两个不同的输入得到相同的哈希值=哈希值冲突
在这里插入图片描述
HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。

HashMap 基于 Hash 算法实现的:

  1. 当我们往Hashmap中put元素时,利用key的hashCode重新hash计算出当前对象的元素在数组中的下标
  2. 存储时,如果出现hash值相同的key,此时有两种情况。(1)如果key相同,则覆盖原始值;(2)如果key不同(出现冲突),则将当前的key-value放入链表中
  3. 获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值

理解了以上过程就不难明白HashMap是如何解决hash冲突的问题,核心就是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。

需要注意Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值