SkipList跳表

SkipList,跳表,是一种有序的数据结构,可以作为平衡树的一种替代。本质上是一种利用稀疏索引加速链表查询的一组数据+索引的结构。

平衡树一般指BST和 红黑树等数据结构,这种数据结构解决了 排序树的不平衡问题,但带来了旋转,变色等问题,在并发场景下锁的粒度很大,会一定程度上影响性能,并且实现比较复杂。相对而言,SkipList避免了这些问题。

实现

跳表一般基于有序链表实现。首先是链表的排序问题,对于链表的来说,排序的问题其实等价于怎么找到新增节点的在有序链表中插入位置

对于数组而言,只需要利用二分法查找到对应的位置,然后插入,并移动之后的元素,主要的开销在于拓展内存以及移动元素。

链表没法这么处理。链表的优势在于插入后无需移动后续元素,但无法跳跃查询,主要开销在于定位插入位置。

结合两者实际上就是跳表的基本思想:底层数据用有序链表维护,方便数据插入;在底层数据节点之上构建多层不同的稀疏索引(比如从上往下不断变密集),加速节点的查询,快速定位。


比如底层索引6节点,第一层索引在中点处[ (0 + 6) / 2]添加索引,第一层索引将底层分成两个分区,第二层索引再在两个分区的中点添加索引,以此类推。

索引节点+数据节点就是跳表的核心,但这又有了另一个问题:怎么样便利的维护索引节点?

显然,将每层的分区的中点作为索引节点是不合适的,因为节点的增减是一种常见需求,每次数据节点的增减都会导致索引节点的变化,带来不少额外的开销。我们需要一种与数据节点数量无关的、确定索引节点位置的方法。

基本的思路就是使用随机化。在每次增加节点时确定是否需要此节点上建立索引节点。

比如对于一个最高XX层的跳表,设底层NN个数据节点。每次添加节点时,以1/(2n)1/(2^n)判断是否要在前nn层添加索引节点(只有本层有索引节点才能往上层添加索引节点)。
对于第KK层,将有N/2kN / 2^k个节点,与取分区中点作为索引节点等价。

数据结构

type SkipListNode struct {data *codec.EntrynextPtrs []*SkipListNode
}type SkipList struct {header, tail *SkipListNodelevel        intsize         intrwmtx        *sync.RWMutexmaxSize      int
}

操作

值得关注的只有查询和插入节点两个操作。

查询

最核心的步骤是由上至下,利用每层的稀疏索引二分查找定位到需要的节点,或者位置。

// findPreNode find the node before node.key
func (sl *SkipList) findPreNode(key []byte) (*SkipListNode, bool) {// from top to bottomh := sl.headerfor i := sl.level - 1; i >= 0; i-- {for h.nextPtrs[i] != nil && bytes.Compare(h.nextPtrs[i].data.Key, key) != 1 {if bytes.Equal(h.nextPtrs[i].data.Key, key) {return h, true}h = h.nextPtrs[i]}}return nil, false
}

插入

首先要定位到插入的位置,插入,再随机化创建索引。

func (sl *SkipList) randomLevel() int {ans := 1rand.Seed(time.Now().Unix())for rand.Intn(2) == 0 && ans <= defaultMaxLevel {ans++}return ans
}func (sl *SkipList) Insert(data *codec.Entry) *SkipListNode {sl.rwmtx.Lock()defer sl.rwmtx.Unlock()h := sl.headerupdateNode := make([]*SkipListNode, defaultMaxLevel) // stores the node before newNode// search form the top levelfor i := sl.level - 1; i >= 0; i-- {// loop: 1. current nextPtrs is not empty && data is small than inserted one, curData < insertedDatafor h.nextPtrs[i] != nil && h.nextPtrs[i].data.Less(data) {h = h.nextPtrs[i]}updateNode[i] = h}// choose level to insertlvl := sl.randomLevel()if lvl > sl.level {// Insert into higher level, we need to create header -> tailfor i := sl.level; i < lvl; i++ {updateNode[i] = sl.header}sl.level = lvl}// insert after updatedNoten := NewSkipListNode(lvl, data)for i := 0; i < lvl; i++ {n.nextPtrs[i] = updateNode[i].nextPtrs[i]updateNode[i].nextPtrs[i] = n}sl.size++return n
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/138730.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ 消息应答

每日一句 物是人非事事休,欲语泪先流。 概述 为了保证消息在发送过程中不丢失,RabbitMQ引入了消息应答机制, 消费者在接收到消息并且处理该消息后,告诉RabbitMQ它已经处理了,RabbitMQ可以把消息删除了。 自动应答 消息发送后立即被认为已经传送成功,这种模式需要在…

VB求平均值

VB求平均值 Private Function pj(x() As Integer) As SingleDim m%, n%, i%, s%m LBound(x): n UBound(x)For i m To ns s x(i)Next ipj s / (n - m 1) End Function Private Sub Command1_Click()Dim a%(1 To 10), i%, aver!For i 1 To 10a(i) Int(Rnd() * 10) 随机…

安装Anaconda与pytorch,在IDEA中配置环境进行编程

1.官网下载与自己python版本匹配的Anaconda(注意&#xff0c;要想成功安装pytorch&#xff0c;python版本也要对应pytorch的相关版本) Anaconda官网最新版本 与自己python版本不否请查找自己版本anaconda版本对应 清华大学镜像下载 2.安装时勾选添加环境变量或者手动添加&am…

CMD脚本实战教程

要在 Windows 11 上编写一个自定义关机的 CMD 脚本文件&#xff0c;你可以创建一个扩展名为 .bat 或 .cmd 的文本文件&#xff0c;并在其中编写脚本。 一、常用语法 rem&#xff1a;注释 pause&#xff1a;暂停正在执行的批处理文件&#xff0c;并提示用户按键之后继续执行 r…

【数模研赛思路】2023华为杯研究生数学建模竞赛选题建议及CDEF题思路

大家好呀&#xff0c;全国研究生数学建模竞赛今天早上开赛啦&#xff0c;在这里先带来初步的选题建议及思路。 目前团队正在写E题完整论文&#xff0c;此外C已经完成了第一问代码及结果&#xff0c;本文章只是一个比较粗略的文字版思路&#xff0c;更加详细的半小时视频讲解版…

Windows AD 组策略 安全加固

一、密码策略 &#xff08;1&#xff09;Enforce password history&#xff08;强制密码历史&#xff09; &#xff08;2&#xff09;aximum password age&#xff08;密码最长使用期限&#xff09; &#xff08;3&#xff09;Minimum password age&#xff08;密码最短使用期限…

基于微信小程序的校园生活管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言运行环境学生微信端的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝1…

浅谈终端安全接入

前言&#xff1a; 随着网络的发展&#xff0c;现代企业大多都会部署企业的有线网络与无线网络&#xff0c;在传统的企业网内&#xff0c;随着越来越多的终端设备接入到公司网络&#xff0c;管理人员控制和审计外部用户接入的企业办公网的难度和工作量也越来越大。而如果允许外…

图的十字链表存储结构

1.其实就是邻接表和逆邻接表的结合&#xff0c;说明白点&#xff0c;就是用箭头表示出弧头&#xff0c;弧尾&#xff0c;以及他们之间的关系 2.顶点结构 3.弧结构 3.这样根据上面的结点十字链表结构就很好分析了

东莞建筑模板批发供应商

东莞作为中国著名的制造业城市&#xff0c;建筑业一直是该地区的重要支柱产业。在建筑施工中&#xff0c;建筑模板是不可或缺的关键材料之一。为满足市场需求&#xff0c;东莞拥有众多专业的建筑模板批发供应商&#xff0c;他们以丰富的经验、优质的产品和专业的服务赢得了客户…

Python练习之列表

1、输入一个包含若干整数的列表&#xff0c;输出新列表&#xff0c;要求新列表中的所有元素来自于输入的列表&#xff0c;并且降序排列。 ainput("输入列表元素&#xff1a;") itema.split(" ") list[eval(x) for x in item] list.sort(keyNone,reverseTr…

人脸修复祛马赛克算法CodeFormer——C++与Python模型部署

一、人脸修复算法 1.算法简介 CodeFormer是一种基于AI技术深度学习的人脸复原模型&#xff0c;由南洋理工大学和商汤科技联合研究中心联合开发&#xff0c;它能够接收模糊或马赛克图像作为输入&#xff0c;并生成更清晰的原始图像。算法源码地址&#xff1a;https://github.c…

2023-2024年最新大数据学习路线

文章目录 2023-2024年最新大数据学习路线大数据开发入门*01*阶段案例实战 大数据核心基础*02*阶段案例实战 千亿级数仓技术*03*阶段项目实战 PB级内存计算04阶段项目实战 亚秒级实时计算*05*阶段项目实战 大厂面试*06* 2023-2024年最新大数据学习路线 新路线图在Spark一章不再…

软考复习 -- 计算机网络

1 网络互连设备 物理层&#xff1a;中继器和集线器&#xff08;多路中继器&#xff09;数据链路层&#xff1a;网桥和交换机&#xff08;多端口网桥&#xff09;网络层&#xff1a;路由器应用层&#xff1a;网关 2 广播域和冲突域 3 协议簇 4 网际层协议 4 TCP和UDP 4.1 TC…

打开常用软件出现msvcp140.dll丢失的解决方法,msvcp140.dll是什么东西?

在我们使用计算机的过程中&#xff0c;有时候会遇到一些错误提示&#xff0c;其中“找不到 msvcp140.dll”就是比较常见的一种。那么&#xff0c;msvcp140.dll 到底是什么呢&#xff1f;为什么会出现找不到的情况&#xff1f;丢失 msvcp140.dll 又会对计算机产生什么影响&#…

腾讯Behaviac Designer 和Unity连调行为树

1. 克隆源码 https://github.com/Tencent/behaviac/ 2. 编译生成BehaviacDesigner.exe 3. 找到并打开BehaviacDesigner.exe&#xff08;先不急着填弹出的路径workspace 设置框&#xff09; 4. 新建一个Unity 空工程&#xff0c;并在此处下载behaviac unitypackage 5. Unity中…

ATFX汇市:为什么英央行维持利率不变,而不是加息25基点?

ATFX汇市&#xff1a;9月21日&#xff0c;英国央行9月利率决议宣布&#xff0c;维持5.25%的基准利率不变&#xff0c;此前市场预期英央行将会加息25基点。消息公布后&#xff0c;GBPUSD五分钟内从最高点1.2300下跌至1.2239&#xff0c;跌幅61基点。英国央行会议纪要中提到&…

5.数学公式中-符号加粗

在 LaTeX 中&#xff0c;\boldsymbol 命令用于将数学公式中的符号或字母加粗显示&#xff0c;以突出显示它们或强调它们的重要性。通常&#xff0c;这个命令用于加粗矢量、矩阵、符号等。 要使用 \boldsymbol&#xff0c;您需要在数学模式中&#xff08;例如&#xff0c;在 \[…

技术分享| anyRTC音视频混流技术解析

一&#xff0c;简介 在视频通讯场景中&#xff0c;比如会议、直播等经常能看到图像合成的场景。图像合成是在指定的一块画面区域&#xff0c;在这个区域内&#xff0c;按画面的位置(坐标)布局&#xff0c;将区域中的每个视频画面的像素混合计算成一个像素&#xff08;RGB&…

Haproxy负载均衡集群 超详细 (附部署实例)

Haproxy 一、Web集群调度器1.1 常用的Web集群调度器1.2 常用集群调度器的优缺点&#xff08;LVS ,Nginx,Haproxy)1.2.1 Nginx1.2.2 LVS1.2.3 Haproxy 1.3 LVS、Nginx、Haproxy的区别 二、Haproxy2.1 简介2.2 Haproxy的主要特性2.3 Haproxy应用分析2.4 Haproxy的调度算法(负载均…