TreeMap简析

本文简要介绍了红黑树及其与2-3树的关系,重点在于理解红黑树如何通过2-3树的演变而来。接着,文章转向TreeMap,它是基于红黑树的Java集合,用于实现有序映射。TreeMap主要利用红黑树的特性,提供高效的查找、遍历操作。虽然详细源码未展开,但提到了其常用操作如entrySet和keySet的实现。文章还提及了与Redis有序集合SortSet的相似性,但SortSet使用了跳表数据结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

红黑树的演化

既然叫TreeMap,那么肯定是建立在树这种数据结构的Map了,是什么数呢?叫红黑树。
说到红黑树,就不得不说二叉查找树。二叉查找树是每个节点大于其左子节点而小于其右子节点的二叉树。如果只是满足定义,那么下图所示都满足条件:
这里写图片描述
但是左图退化成链表的存在,肯定不是我们所需要的,那么既然这样,肯定需要有种算法,来保证树不会退化,保证查找的速度。
理想中的情况应该是上图右所示的二叉树,二分法查找logN时间复杂度,最快的速度。但是如何进行维护这么一颗树,也就是如何平衡,因为每次插入,删除都有可能打破现有的平衡,那么就需要重新平衡,而维护完全的平衡二叉查找树,却太过复杂。
为了在维持平衡和查询速度进行折中,AVL树诞生,它要求在任何节点的两个子树的高度最大差别为1,AVL树通过一些列的旋转操作使树保持平衡,由于它的要求还是比较严格,导致维持平衡的代价过大,从而没有成功真正使用的经典数据结构。
而红黑树确实非常适合,而它的实现思路是借助2-3树的,且2-3树建立树的过程相对简单,我们就以2-3树开始分析,
首先看先2-3树的特性,这是摘抄自百度文库的定义:
数据项放入2-3树节点中的规则是:
1. 2-节点有两个孩子,必含一个数据项,其查找关键字大于左孩子的查找关键字,而小于右孩子的查找关键字。
2. 3-节点有三个孩子 ,必含两个数据项,其查找关键字S和L满足下列关系:S大于左孩子的查找关键字,而小于中孩子的查找关键字;L大于中孩子的查找关键字,而小于右孩子的查找关键字。
何为2-节点,何为3-节点呢?看下图:
这里写图片描述
这就是一棵2-3树,所有的叶子节点都在同一层,这就是所谓的高度平衡。从图上可以看出,虽然不是严格的二叉树,但是从图上大概可以估算出查找的时间复杂度应该是很接近logN。
那2-3树是怎么维持平衡的呢?如何进行插入呢?简单说,先进行遍历,找到相同的就替换,没有相同的就找到最后的叶子节点,然后把新节点挂在树的底部。我们看下图是我用ACEJHLPRSXM顺依次构造的二叉树过程(删除的操作有兴趣可以自己研究),能够清楚的演示二叉树维持平衡的过程。2-3树会因为插入的顺序不同,而出现不同的结构。
这里写图片描述
那什么这和红黑树到底有什么关系了。由于2-3树节点的不统一,造成了编程的困难,为了应付这种情况,用标准的二叉树和一些额外的信息,来表示2-3树,这之一就是红黑树,用红链将2个2-节点连起来作为构成一个3-节点。
下图就是有2-3树变化到红黑树的结构(左边的是2-3树的结构),由图可以清楚的看出,其实就是一种演变,我们可以通过2-3树相同的步骤,来组件红黑树,具体的构造有兴趣的可以自己研究。
这里写图片描述
数据结构的分析就到此为止吧,毕竟本文的主要目的是 TreeMap。

TreeMap的讲解

TreeMap是建立在红黑树的基础上的,那么常用的操作有哪些呢?

方法描述
V put(K key, V value)插入操作
V get(Object key)get操作
V remove(Object key)删除操作
Set< K > keySet()键集合
Set< Map.Entry > entrySet()值集合
Map.Entry firstEntry()获取第一个节点(根或者最左)
Map.Entry lastEntry()获取最后一个节点(根或者最右)

突然觉得没什么要写的了,因为treeMap整个就是一颗红黑树,一颗平衡的查找树,按照key来进行排序,图都很清楚了,如果在把java源码贴出来,感觉有点凑字的感觉。entrySet和 keyset几乎一样的代码,都是遍历器的实现,一个个按照顺序取出。红黑树是颗平衡树,本身就是为了考虑有序和遍历速度的平衡而设计的,节点最坏的情况为:红黑相间的路径长度是全黑路径长度的2倍,所以,遍历还是非常快速,时间复杂度为logN。
其他的方法,好像不怎么常用,treemap本身好似就不常用。但是常用的一种数据结构好像非常类似treemap,redis的有序集合sortset,通过分数来排序,附带value,不过sortset并不是用的红黑树实现,而是跳表(Skip List),有兴趣可以自行研究。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值