SkipList 以及高度的确定

转载:https://www.cnblogs.com/lnlvinso/p/8848883.html

  结果:skiplist的高度是个随机值。

SkipList理解

  记下自己对跳表SkipList的理解。

        SkipList采用空间换时间的思想,通过增加数据间的链接,达到加快查找速度的目的。

        数据库LevelDB和RocksDB中用到了SkipList,Redis中的有序set即zset也用到了SkipList。Java中也提供了ConcurrentSkipListMap,在并发量大的情况下,ConcurrentSkipListMap性能好。

        先看SkipList的查找过程,引用网上的经典图片,查找19。注意的是数据是有序的。

          查找的过程从上至下,查找指针所经历的位置顺序如图中的1,2,3,直到找到目标数据19。

          再加一张图,是怎么二分法查找的。

  

           

    SkipList中创建新结点时,产生一个在1~MAX_LEVEL之间的随机level值作为该结点的level。每个节点的高度是随机的。

            MAX_LEVEL可以静态指定,也可以动态增长。

            关于MAX_LEVEL,觉得这篇文章的解释是比较清楚的:https://blog.csdn.net/kisimple/article/details/38706729。下面是复制了部分的内容

            

   每个节点所能reach到的最远的节点是随机的,正如作者所说,SkipList使用的是概率平衡而不是强制平衡。

  O(logN)?

   既然是随机算法,那怎么能保证O(logN)的复杂度?SkipList作者在论文中有给出了说明,这里从另一个角度说下我的理解。先定义一下,A node that has k forward pointers is called a level k node。假设k层节点的数量是k+1层节点的P倍,那么其实这个SkipList可以看成是一棵平衡的P叉树,从最顶层开始查找某个节点需要的时间是O(logpN),which is O(logN) when p is a constant。

  下面看下Redis与LevelDB中实现SkipList所使用的随机算法。

  Redis

     在t_zset.c中找到了redis使用的随机算法。

 

/* Returns a random level for the new skiplist node we are going to create.* The return value of this function is between 1 and ZSKIPLIST_MAXLEVEL* (both inclusive), with a powerlaw-alike distribution where higher* levels are less likely to be returned. */
int zslRandomLevel(void) {int level = 1;while ((random()&0xFFFF) < (ZSKIPLIST_P * 0xFFFF))level += 1;return (level<ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}

 

    执行level += 1;的概率为ZSKIPLIST_P,也就是说k层节点的数量是k+1层节点的1/ZSKIPLIST_P倍。ZSKIPLIST_P(这个P是作者论文中的p)与ZSKIPLIST_MAXLEVEL在redis.h中定义,

#define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^32 elements */
#define ZSKIPLIST_P 0.25      /* Skiplist P = 1/4 */

    所以redis中的SkipList相当于是一棵四叉树。

  LevelDB

    在skiplist.h中找到了LevelDB使用的随机算法。

template<typename Key, class Comparator>
int SkipList<Key,Comparator>::RandomHeight() {// Increase height with probability 1 in kBranchingstatic const unsigned int kBranching = 4;int height = 1;while (height < kMaxHeight && ((rnd_.Next() % kBranching) == 0)) {height++;}assert(height > 0);assert(height <= kMaxHeight);return height;
}
 (rnd_.Next() % kBranching) == 0)的概率为1/kBranching,所以LevelDB中的SkipList也是一棵四叉树(kBranching = 4;不就是这个意思吗^_^)。

            总结:skiplist是有序的,采用类似二分法方式进行查找。查找、插入的平均时间复杂度是O(ln2)。

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

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

相关文章

20个正则表达式,举一反三,相信对你很有用

转载:https://www.cnblogs.com/wxd0108/p/5580772.html 正则表达式经常被用于字段或任意字符串的校验&#xff0c;如下面这段校验基本日期格式的JavaScript代码&#xff1a; var reg /^(\\d{1,4})(-|\\/)(\\d{1,2})\\2(\\d{1,2})$/; var r fieldValue.match(reg); if(rnull)a…

约瑟夫环问题---循环单链表

约瑟夫环问题是比较经典的问题&#xff0c;原来做的题目是依次输出数字&#xff0c;而原来的循环链表结构不改变&#xff0c;今天遇到一道题是要求按照顺序重新组成一个循环单链表。 题目&#xff1a;一些人围坐一圈报数&#xff0c;形成一个循环单链表&#xff0c;当报数是m或…

IIS AppCreate子目录的错误(0x80020006)

这几天做了升级用的安装包,需要在原来的ASP 的虚拟目录下&#xff0c;再创建一个新的ASPNet 虚拟目录。上网查了C# iis设定的资料&#xff0c;按照上面一路做下来&#xff0c;还是无法成功过。 代码只有两行&#xff0c;如下&#xff1a;DirectoryEntry siteVDir new Director…

网络通信TCP协议三次握手

刚刚看linux公社看见里面一个讲TCP的文章&#xff0c;文章讲的很有意思生动形象&#xff0c;很有助于对TCP协议的理解和掌握&#xff0c;所以转载过来方便以后看一下HAHA~~~TCP是什么? TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的、可靠的、 …

聊聊RocksDB Compact

导语 对于 LevelCompact 策略&#xff0c;RocksDB会根据每一层不同的策略计算出CompactScore&#xff0c;根据CompactScore大小来决定那一层将会优先进行Compact&#xff0c;然后选择Level-N 和Level-(N1&#xff09;的文件进行Compact。如何计算CompactScore&#xff1f; 如何…

Android入门逆引手册 - 12 评分条(RatingBar)的使用

这里介绍评分条android.widget.RatingBar类的使用。 ● 评分&#xff08;星&#xff09;的最大数的设置&#xff0c;调用setNumStars()方法。● 现在的评分的设置&#xff0c;调用setRating()方法。 例程源码(Java)[java]RatingBar ratingBar (RatingBar)findViewById(id.rati…

数据库事务的四大特性以及事务的隔离级别

本篇讲诉数据库中事务的四大特性&#xff08;ACID&#xff09;&#xff0c;并且将会详细地说明事务的隔离级别。 如果一个数据库声称支持事务的操作&#xff0c;那么该数据库必须要具备以下四个特性&#xff1a; ⑴ 原子性&#xff08;Atomicity&#xff09; 原子性是指事务包含…

程序员面试的一些注意点

一、前言 自己即将踏上求职的征程&#xff0c;所以整理一篇有关于程序员面试的小窍门&#xff0c;帮助自己和正在求职、即将求职的一些小伙伴跳过一些坑。 二、简历制作1. 不要放头像普通人大概率都不是帅哥美女&#xff0c;所以不想让外观成为评判标准的就不要放照片上去了。2…

如何解决数据倾斜问题?

转载&#xff1a;https://blog.csdn.net/Mr_HHH/article/details/89399518 今天在工作中遇到了数据倾斜的问题&#xff0c;一条SQL执行了8小时才执行完&#xff0c;看计划是先join再做distinct&#xff0c;卡在了join上&#xff0c;数据量比较大&#xff0c;并且重复数据比较多…

白盒测试不是测试,更不高级

测试不仅仅是软件概念&#xff0c;但白盒测试仅仅是软件概念。 上面这句话足以说明白盒测试不是测试&#xff0c;至少不等同于测试。 认为白盒测试更牛逼的一个常用论据是白盒测试需要对代码本身更高的熟悉程度&#xff0c;但说这样的话的人往往没有搞清楚测试究竟需要什么样的…

剑指Offer题解(Python版)

https://blog.csdn.net/tinkle181129/article/details/79326023# 二叉树的镜像 链表中环的入口结点 删除链表中重复的结点 从尾到头打印链表 斐波那契数列 跳台阶 变态跳台阶 矩形覆盖 把字符串转换成整数 平衡二叉树 和为S的连续正数序列 左…

Paypal 在线支付接口应用从零开始,第2节,[支付API原理及流程]

今天看看Paypal支付流程和简单的认证原理,我画了一张图.应该能表达这两点意思了我们的站点名字,为了好理解,暂且就定为西狐的网站吧.点此查看清晰原图恩,理论知识很重要哈,先把这图理解了,下一步我们编程使用沙盒测试就很简单了.如果想更多研究一下还可直接查看Paypal官方提供的…

C语言指针深度理解

指针是&#xff23;语言中广泛使用的一种数据类型。 运用指针编程是&#xff23;语言最主要的风格之一。利用指针变量可以表示各种数据结构&#xff1b; 能很方便地使用数组和字符串&#xff1b; 并能象汇编语言一样处理内存地址&#xff0c;从而编出精练而高效的程序。指针极大…

PLSQL DEVELOPER 使用技巧

为什么80%的码农都做不了架构师&#xff1f;>>> 1、右键菜单 在PL/SQL Developer&#xff08;下面简称PLD&#xff09;中的每一个文本编辑窗口&#xff0c;如SQL Window&#xff0c;Command Window和Porgram Window&#xff0c;右键点击某个对象名称&#xff0c;会…

为什么不能同时用const和static修饰成员函数?

const修饰的函数: 表示在该函数体内不能修改成员的值&#xff0c;会在函数中添加一个隐式的参数const this*. static修饰的函数没有this指针&#xff0c;与const的用法冲突。 但可以使用static和const修饰成员。 例子如下&#xff1a; class Singleton { public: stati…

对于一颗完全二叉树,要求给所有节点加上一个pNext指针,指向同一层的相邻节点;如果当前节点已经是该层的最后一个节点,则将pNext指针指向NULL;给出程序实现,并分析时间复杂度和空间复杂度。

typedef struct TNode { int data; TNode* left; TNode* right; TNode* next; }; //时间复杂度为O(n)&#xff0c;空间复杂度为O(n) void addNext(TNode* root) { if (!root) { return; } queue<TNode*> q; q.push(root); while (!q.empty()) { int levelL…

T-SQL DML学习笔记

1. select 语句的基本结构是 select -->From-->where group By Having Order By 2. Exists 条件 Exists 后面括号内的条件语句如果为真的话 这此次查询继续 &#xff0c;如Exists跟的条件语句没有查询到数据则前面语句块的查询不再执行下去 select province…

反射--Class获得

/* Java提供3种方式获得Class对象 * * 不同应用场景&#xff0c;需要不同的方式获得Class对象 * * 方式&#xff1a; * 1.通过字符串&#xff08;全限定类名&#xff09;获得 * 格式&#xff1a;Class clazz Class.forName("字符串"); * 全限定类名&#xff1a;包名…

Android Drawable绘图学习笔记

如何获取 res 中的资源 数据包package&#xff1a;android.content.res 主要类&#xff1a;ResourcesAndroid SDK中的简介&#xff1a;Class for accessing an application’s resources.Class for accessing an application’s resources. This sits on top of the asset mana…

在类中调用delete this问题

转载&#xff1a;https://blog.csdn.net/kuimzzs/article/details/81517451 很多时候&#xff0c;一些定义在类内的变量的生命周期在类外并不是很好的掌控&#xff0c;这样就很容易造成内存泄漏得到问题 比如以下代码&#xff1a; class Test { public: void foo(); pri…