红黑树实现的java集合_红黑树Java语言实现

红黑树的用途

用于快速查找元素,或者说快速根据关键字查询值。和散列表不同,散列表是利用散列函数建立单向映射实现快速查找。红黑树属于二叉查找树,它使得树的深度保持在O[ log(n) ],查找次数不多于最大深度,从而实现快速查找。

红黑树的定义

树中有两种颜色的节点,红色和黑色(顾名思义)

所有终端节点为黑色。终端节点(又称叶子节点)就是null节点

根节点是黑色

不能有两个连续的红色节点(即每个红色节点都有2个黑色节点)

从根节点到终端节点路径上的黑色节点个数相同

红黑树高效的原因

上述4、5最重要,找到终端可谓是最糟糕的情况了,即便的最坏的情况下,黑色节点都相同。那么路径最长的情况下是红黑相间的情况下,最短情况是全部是黑色。显然,到终端最长路径不超过最短路径的2倍。因此能够保证树的深度是O[ log(n) ]的(本人未证明),从而保证了效率。

红黑树的插入

首先要声明一下,除了插入根节点之外,新插入的节点初始的颜色都是红色的(后来可能会调整颜色)

1. 最简单的情况——插入根节点

只需保证根节点为黑色,非常简单。。。

d6f3b5b900f6b7b9779c2946e785ebe9.png

2. 也很简单的情况——新节点的父亲是黑色的

7f4a42530d651d2552219a676fe33397.png

没有任何负面影响,因为即保证了红色节点不连续,又不影响根节点到终端的黑色节点个数。原来是(黑)父亲+(黑)孩子,现在是(黑)父亲+(红)新节点+(黑色)新节点的儿子

3. 新节点的父亲是红色的

这时候就出现了红色节点连续的情况了,需要调整

3.1 新节点的叔叔是红色的

6d7b65c04f409f108a08ffe53684bbe7.png

把爷爷变成黑色,父亲和叔叔变成红色。首先在从太爷爷到终端的黑色节点个数不变,其次这个局部没有红黑相间的情况。但是爷爷和太爷爷之间可能会出现2个连续红色的情况,把爷爷设为新节点(current),继续运行插入规律(上调)。

3.2 新节点的叔叔是黑色的

3.2.1 LL形式

96648c2758ffdd030d7d763d914832ba.png

这时候新的节点和父亲出现了红色相邻的情况。这时候对爷爷进行右单旋,并且爷爷和父亲交换颜色。注意的是可能会丢失父亲的右孩子,它本来就是介于父亲和爷爷的值,正好弥补了爷爷的左孩子。这样依旧保证了红黑树性质,因为父亲是黑色的,不需要上调。

3.2.2 LR形式

1cbe0be477b2a9ed8be4e99fc3304380.png

先说一种一步到位的方法,就是让父亲和爷爷成为新节点的左儿子和右儿子,同时新节点的左子树接到父亲的右子树,新节点的右子树接到爷爷的左子树。新节点和爷爷颜色交换,新节点设为黑色。

显然结果不存在连续的红色节点,根节点到终端的黑色节点数也保持不变。

新节点的左子树本身大于父亲小于新节点,新节点的右子树小于爷爷大于新节点,旋转后依然保持二叉搜索树的性质

35760ffc89860a6522e331cc52d23499.png

再说一种两步到位的方法,先对父亲左单旋,注意新节点的左子树接到父亲的右子树上,否则会丢失节点!这样就转换成了3.2.1 LL形式(对爷爷右单旋)。从编程的角度来说还是一步到位更有效率!

3.2.3 RR形式

是LL的镜像对称模式,一切取反即可,不再累述

3.2.4 RL形式

是LR的镜像对称模式,一切取反即可,不再累述

红黑树 vs AVL树

总结来说,AVL树插入效率小于红黑树,AVL查询效率大于红黑树

AVL可以保证左右子树高度差绝对值不大于1并且是一颗二叉搜索树

插入时,AVL树平衡性强,更容易引起不平衡触发耗时的旋转操作,红黑树只有在父亲是红色时才能触发旋转操作,“容纳\忍耐”能力强一些,因此损耗更低。

查询时候,AVL可以保证左右子树高度差绝对值不大于1,红黑树平衡性更差,所以深度略大,查询效率略低一些。

平均来说,红黑树性能>AVL性能

AVL树介绍,参考我以前的博客:AVL树理解、证明

红黑树Java实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值