后台开发:核心技术与应用实践3.4.3 map的原理

简介:

3.4.3 map的原理


map内部自建一棵红黑树(一种非严格意义上的平衡二叉树),这棵树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的。这里简单讲下红黑树的含义。

先来看下算法导论对R-B Tree的介绍:红黑树,一种二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的。红黑树,作为一棵二叉查找树,满足二叉查找树的一般性质。下面,来了解下二叉查找树的一般性质。

二叉查找树,也称有序二叉树(ordered binary tree),或已排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:①若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;②若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;③任意节点的左、右子树也分别为二叉查找树;④没有键值相等的节点(no duplicate node)。

因为一棵由n个结点随机构造的二叉查找树的高度为lgn,所以二叉查找树的一般操作的执行时间为O(lgn)。但二叉查找树若退化成了一棵具有n个结点的线性链后,则这些操作最坏情况运行时间为O(n)。

红黑树虽然本质上是一棵二叉查找树,但它在二叉查找树的基础上增加了着色和相关的性质使得红黑树相对平衡,从而保证了红黑树的查找、插入、删除的时间复杂度最坏为O(logn)。

它是如何保证一棵n个结点的红黑树的高度始终保持在logn的呢?这就引出了红黑树的5个性质:①每个结点要么是红的要么是黑的;②根结点是黑的;③每个叶结点(叶结点即指树尾端NIL指针或NULL结点)都是黑的;④如果一个结点是红的,那么它的两个儿子都是黑的;⑤对于任意结点而言,其到叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点。

正是红黑树的这5条性质,使一棵n个结点的红黑树始终保持了logn的高度,从而也就解释了上面所说的“红黑树的查找、插入、删除的时间复杂度最坏为O(logn)”这一结论成立的原因。

如图3-3所示,是一颗红黑树(图3-3引自wikipedia:http://t.cn/hgvH1l)。

 

图3-3 红黑树

当在对红黑树进行插入和删除等操作时,对树做了修改可能会破坏红黑树的性质。为了继续保持红黑树的性质,可以通过对结点进行重新着色,以及对树进行相关的旋转操作,即通过修改树中某些结点的颜色及指针结构,来达到对红黑树进行插入或删除结点等操作后继续保持它的性质或平衡的目的。

树的旋转分为左旋和右旋,下面借助图来介绍一下左旋和右旋这两种操作。

1)左旋操作(图3-4)。

 

图3.4 左旋操作示意图

如图3-4所示,当在某个结点pivot上,做左旋操作时,假设它的右孩子y不是NIL[T],pivot可以为任何不是NIL[T]的左子结点。左旋以pivot到Y之间的链为“支轴”进行,它使Y成为该子树的新根,而Y的左孩子b则成为pivot的右孩子,在代码中表示如下所示。

LeftRoate(T, x)

y ← x.right            // y是x的右孩子

x.right ← y.left             // y的左孩子成为x的右孩子

if y.left ≠ T.nil

    y.left.p ← x

y.p ← x.p                   // y成为x的父亲

if x.p = T.nil

    then T.root ← y

else if x = x.p.left

    then x.p.left ← y

else x.p.right ← y

y.left ← x              // x作为y的左孩子

x.p ← y

2)右旋操作(图3-5)。

 

图3-5 右旋操作示意图

右旋与左旋差不多,再此不做详细介绍。

树在经过左旋右旋之后,树的搜索性质保持不变,但树的红黑性质被破坏了,所以红黑树插入和删除数据后,需要利用旋转与颜色重涂来重新恢复树的红黑性质。

由于map的内部实现过于复杂,本章不做详细介绍,有兴趣的读者可自行在网上查资料。

相关文章
|
6月前
|
存储 数据格式
Set和Map的应用场景
Set和Map的应用场景
|
1月前
|
存储 Java API
详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
【10月更文挑战第19天】深入剖析Java Map:不仅是高效存储键值对的数据结构,更是展现设计艺术的典范。本文从基本概念、设计艺术和使用技巧三个方面,详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
51 3
|
2月前
|
数据处理 Python
Pandas中的map函数应用
Pandas中的map函数应用
19 2
|
2月前
|
存储 前端开发 API
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
该文章详细介绍了ES6中Set和Map数据结构的特性和使用方法,并探讨了它们在前端开发中的具体应用,包括如何利用这些数据结构来解决常见的编程问题。
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
|
3月前
|
缓存 安全 测试技术
深入理解 go sync.Map - 基本原理
深入理解 go sync.Map - 基本原理
35 0
|
4月前
|
JSON JavaScript API
JS【详解】Map (含Map 和 Object 的区别,Map 的常用 API,Map与Object 的性能对比,Map 的应用场景和不适合的使用场景)
JS【详解】Map (含Map 和 Object 的区别,Map 的常用 API,Map与Object 的性能对比,Map 的应用场景和不适合的使用场景)
100 0
|
6月前
|
存储 C++ 容器
【STL】map和set的原理及其使用
【STL】map和set的原理及其使用
|
6月前
|
Python
【Python 基础】解释map函数的工作原理
【5月更文挑战第6天】【Python 基础】解释map函数的工作原理
|
6月前
|
存储 缓存 安全
掌握Go语言:Go语言Map,高效键值对集合的应用与注意事项详解(26)
掌握Go语言:Go语言Map,高效键值对集合的应用与注意事项详解(26)
|
6月前
|
人工智能 自然语言处理 Kubernetes
LLM 技术图谱(LLM Tech Map)& Kubernetes (K8s) 与AIGC的结合应用
LLM 技术图谱(LLM Tech Map)& Kubernetes (K8s) 与AIGC的结合应用
326 0
下一篇
无影云桌面