首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

数据结构学习——skiplist跳表

目录 1.skiplist简介 2.skiplist核心思想 3.skiplist原理 3.1 跳表的查找 3.2 跳表的插入 3.3 跳表的删除 4.skiplist简单实现 ---- 1.skiplist...简介 Skiplist是一个用于有序元素序列快速搜索的数据结构,由美国计算机科学家William Pugh发明于1989年。...2.skiplist核心思想 先从链表开始,如果是一个单链表,那么我们知道在链表查找一个元素I的话,需要将整个链表遍历一次,时间复杂度为O(n)。...3.skiplist原理 skiplist的结构定义如下: 由多层结构组成; 每一层都是一个有序的链表; 最底层(Level 1)的链表包含所有元素; 如果一个元素出现在 Level i 的链表,则它在...发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

66110

数据结构之链表

一、概念 (1)数组的线性序是由数组的下标决定的,链表的顺序是由各对象的指针所决定的 (2)链表结点结构 node *prev; node *next; int key; (3)链表结点 node...= NULL) x->next->pre = x->pre; delete x; } (2)有哨兵的情况 //链表结点结构 struct node   {       node *pre;  ...node* x) { x->pre->next = x->next; x->next->pre = x->pre; delete x; } 三、练习 10.2-1   能,能   10.2-2  ...把哨兵的值置为一个不可能与x相等的值   10.2-1 能,能 10.2-2 //结点 struct node { node *pre;//为了方便实现出栈操作 node *next; int key...   //依次修改指针,让q是p->next,令q->next=p while(1)       {           r = q->next;           q->next = p;

572100
您找到你想要的搜索结果了吗?
是的
没有找到

函数依赖总结

关系模式的冗余和异常 数据冗余是指同一个数据在系统多次出现。 由于数据的冗余,在对数据进行操作时会引发各种异常:修改异常、插入异常、删除异常。根本原因是数据冗余可能造成操作后数据不一致现象。...在数据库,FD是对关系模式R的一切可能的关系r定义的。对于当前关系r的任意两个元组,如果X值相同,则要求Y值也相同。这种依赖称为函数依赖。记为X->Y, 读作“X决定Y”,或“Y依赖与X”。...这个问题就是逻辑蕴含问题。 设F是关系模式R上的一个函数依赖集合,X->Y是R上的一个函数依赖。如果对于R上的每个满足F的关系r也满足X->Y,那么称F逻辑蕴含X->Y。记为 F |= X->Y。...设U是关系模式R的属性集,F是R上成立的函数依赖集。FD的推广规则如下: 自反性:若X1⊆X⊆U,则X->X1R上成立。...如果X->U在R上成立,但X的任一真子集X1->U在R上不成立,则称X是是R的一个候选键。 一般键都是指候选键。

76420

【redis源码学习】跳跃表

2、有一个头节点,指向一个64层结构。还有个尾结点。 3、除头结点外,层次最高的层数记录在 level 4、length记录了最底层链表的长度。 5、红色部分有往回指的。...寻找插入位置 2、调增跳跃表高度 3、插入节点 4、调整backward 看似不难,谁写谁知道。...x; } 第一次进入for循环: 1)x为头,i=12)rank[1] = 0; 3)进入while循环; 4)rank[1] = 1;x成为第一个节点(也就是update(1)那边) 5...update[i]=x; 第二次进入for循环(层级下降): 1)x为第一个节点,i=0; 2)rank[0]=rank[1]=13)进入循环,这时已经下降一层了。...由于目标level=2,所以会进入分支。 1)rank[2]=0,因为update[2]是头结点。 2)update[2]是头结点。 3)先给level赋个值,后面会调整。 接下来干嘛?

41020

二叉树的遍历回顾

令当前根节点为V,左孩子和右孩子分别为L和R,对于当前这个局部,访问的次序有VLR、LVR、LRV 共3种,根据V所在的访问次序,分别称之为先序、序和后续。...因为L和R也是树,VLR、LVR和LRV可以对L和R进一步展开,展开时也是按相应的先序、序和后续方式访问。L和R被当成新的V,形成递归。 ?...序遍历 traversal(x->rChild, visit); // visit(x->data); // 后序遍历 } 3种方式对应的遍历路径如下, ?...通过先序、序和后序遍历,线性化得到的序列分别为VLR、LVR和LRV的彻底展开,序列每个局部也都符合先序、序和后序的次序。 下面看一下,不同遍历的迭代实现,在于洞察不同规则下访问路径的特点。...= x->parent) //若栈顶非当前节点的父亲(则必为其右兄),此时需 gotoHLVFL(S); //在以其右兄为根的子树,找到HLVFL(相当于递归深入其中)

56710

redis跳跃表源码详解

这个示例update[0]指向的是o2, update[1]也指向o2, update[2]和update[3]指向o1, update[4]-updatep[31]指向的是头结点。...如上例,rank[0]表示与update[0]指向的节点也就是o2的排位,故rank[0]=2,rank[1]=2, rank[2]=rank[3]=1....在插入一个node的时候,层高是随机的可以看zslRandomLevel这个函数,level是1~32之间的一个数值。如上例子,我们新插入的节点,level=3。...zslDeleteNode其实也挺简单的 1,更新与要删除节点x有指向关系的节点的span 与 foward 2, 调整后向节点,可能的话也变更tail节点 3,调整zskiplist的level 4,...比如我们想要删除的start为2,end为3.那么此时 update[0],update[1]应该指向的是o1节点,update[2],update[3]也指向的是o1节点, 而update[4]则是zsl

2.3K51

L2-006 树的遍历 (25 分)

L2-006 树的遍历 (25 分) 给定一棵二叉树的后序遍历和序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。...输入格式: 输入第一行给出一个正整数N(≤30),是二叉树结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。 输出格式: 在一行输出该树的层序遍历的序列。...输入样例: 7 2 3 1 5 7 6 4 1 2 3 4 5 6 7 输出样例: 4 1 6 3 5 7 2 #include using namespace std;...; //后序的最后一个是根节点 for(i = 0; i < n; i ++) { if(a[i] == b[n - 1]) break; // 找到序的这个点,就是左右子树的分界线...>data); if(x->lc)q.push(x->lc); if(x->rc)q.push(x->rc); } } printf

15810

Redis(2)——跳跃表

我们在上一篇中提到了 Redis 的五种基本结构,有一个叫做 有序列表 zset 的数据结构,它类似于 Java 的 SortedSet 和 HashMap 的结合体,一方面它是一个 set 保证了内部...比如,一个节点随机出的层数是 3,那么就把它链入到第 1 层到第 3 层这三层链表。为了表达清楚,下图展示了如何通过一步步的插入操作从而形成一个 skiplist 的过程: ?...现在我们假设从我们刚才创建这个结构查找 23 这个不存在的数,那么查找路径会如下图: ?...level : ZSKIPLIST_MAXLEVEL; } 直观上期望的目标是 50% 的概率被分配到 Level 1,25% 的概率被分配到 Level 2,12.5% 的概率被分配到 Level 3...__biz=MzA4NTg1MjM0Mg==&mid=2657261425&idx=1&sn=d840079ea35875a8c8e02d9b3e44cf95&scene=21#wechat_redirect

87430

走近源码:Redis跳跃列表究竟怎么跳

一维有序列表 如上图,我们要查找一个元素,就需要从头节点开始遍历,直到找到对应的节点或者是第一个大于要查找的元素的节点(没找到)。时间复杂度为O(N)。...这个例子遍历的节点不比一维列表少,但是当节点更多,查找的数字更大时,这种做法的优势就体现出来了。还是上面的例子,如果我们要查找的是39,那么只需要访问两个节点(7、39)就可以找到了。...为了避免插入操作的时间复杂度是O(N),skiplist每层的数量不会严格按照2:1的比例,而是对每个要插入的元素随机一个层数。...level : ZSKIPLIST_MAXLEVEL; } 其中ZSKIPLIST_P的值是0.25,存在上一层的概率是1/4,也就是说相对于我们上面的例子更加扁平化一些。...然后调用zslCreateNode函数创建新的节点。 创建好节点后,就根据搜索路径数据提供的位置,从第一层开始,逐层插入节点(更新指针),并其他节点的span值。

91730

浅析SkipList跳跃表原理及代码实现

3、7、12等点,因此查找的复杂度为O(n/2)。...下面我们将从如下几个方面来探讨跳跃表的操作: 1、重要数据结构定义 2、初始化表 3、查找 4、插入 5、删除 6、随机数生成器 7、释放表 8、性能比较 (一)重要数据结构定义 从图3,...NIL_节点会在后续全部代码实现可以看到。 (三)查找 查找就是给定一个key,查找这个key是否出现在跳跃表,如果出现,则返回其值,如果不存在,则返回不存在。...} } (四)插入 插入包含如下几个操作:1、查找到需要插入的位置 2、申请新的结点 3、调整指针。...2、skiplist.h 接口声明以及重要数据结构定义 3、skiplist.cpp 接口的具体实现 4、random.h 随机数生成器 -----------------------------

59730

零基础手把手带你阅读Redis源代码系列-ZSet底层原理详解(跳表SkipList)

0 13352110901 (integer) 3获取所有号码:> ZRANGEBYLEX phone - +1) "13100111100"2) "13110114300"3) "13132110901"4...234、5;L1 层级共有 3 个节点,分别是节点 23、5;L2 层级只有 1 个节点,也就是节点 3 。...跨度用于计算这个节点在跳表的排位。具体怎么做的呢?...图片如果要查找「元素:abcd,权重:4」的节点,查找的过程是这样的:先从头节点的最高层开始,L2 指向了「元素:abc,权重:3」节点,这个节点的权重比要查找节点的小,所以要访问该层上的下一个节点;但是该层的下一个节点是空节点...( leve2指向的是空节点),于是就会跳到「元素:abc,权重:3」节点的下一层去找,也就是 leve1;「元素:abc,权重:3」节点的 leve1 的下一个指针指向了「元素:abcde,权重:4

1.2K61

究竟深度学习在干什么?

这很容易回答,有2的(M乘2的N次方)次方。这是一个极端惊人的数目。如果仅看文字没有感觉的话,可以试试M=1,N=10,在代入之后,可以看到这个数远大于2的1000次方,或者10的300次方。...我们从2-1 RBM看起,这是最简单的神经网络,有两个实参数。这样的模型,当然是一个学习机。因为仅有两个实参数,学习就是调整这两个实参数,学习也就相当于在参数在一个二维平面R上的运动。...这样,我们从前面讲的机械式学习的角度看,就很清楚,2-1 RBM是这样一回事:这个二维平面R被切成6个区域,每一个区域对于一个X-形式,在学习,如果参数从一个区域跨到另一个区域,就相当于X-形式换成了另一个...我们然后对3-1 RBM,N-1 RBM,N-M RBM都做了讨论,也都清楚地看到这个情况:把参数空间切成若干区域,而每一个区域对应一个X-形式,却是普遍的。...2. 在任何一个这样的区域中,虽然参数可以很不同,但是,其实都代表同一个X-形式,而相应的处理也是相同的。仅有在参数跨过边界,进入不同区域时,才会发生不同的X-形式,才会有不同的处理。 3.

50630

实现一个红黑树

红黑树在数据结构,如果提到编码和压缩绕不开 Hoffman 树,如果从快速获取搜索的树结构那么就离不开红黑树,哈希表设计,从数组加链表,不行我就数组加红黑树,大名鼎鼎的 epoll 也开始起了红黑树...#define RED1#define BLACK 2typedef int KEY_TYPE;typedef struct _rbtree_node {unsigned char color;...= T->nil) { //1 2y->left->parent = x;}y->parent = x->parent; //1 3if (x->parent == T->nil) { //1 4T->...= T->nil) {x = x->left;}return x;}该函数能找出某个节点最左的子节点,当然如果我们默认红黑树按顺序排列,那这个节点就是以 x 为根节点的最小值。...left = T->nil; //设置为红色节点z->right = T->nil;z->color = RED;rbtree_insert_fixup(T, z); //不断向上调整}删除节点还是先前讨论

11400

再也不用担心STL的红黑树了。。。

C++ STL源码剖析之红黑树 0.导语 在STL源码中有两段话,简单翻译后如下: STLRed-black tree(红黑树)class,用来当做SLT关系式容器(set,multiset,map...,也指向红黑树的最左节点,以便用常数时间实现begin(),并且也指向红黑树的最右边节点,以便 set相关泛型算法(set_union等等)可以有线性时间表现. (2)当要删除的节点有两个子节点时,其后继节点连接到其位置..._y ---------> _x T3 // / \ / \ // T2 T3 T1 T2 void leftRotate...1_1.png case 2:U为黑色,考虑N是P的左孩子还是右孩子。 case2.1 如果是右孩子,先进行左旋转,再进入下一种情况。 ?...2_1.png case2.2 可能是上述情况变化而来,但不一定是!策略为:右旋转,改变颜色。 ? rb2_2.png 经过上述源码的分析得知,红黑树插入为镜像变换,另一种情况刚好相反。

1.9K00

Redis使用及源码剖析-5.Redis跳跃表-2021-1-19

文章目录 前言 一、跳表节点实现 二、跳表实现 三、跳表API 1、随机生成层数 2创建跳表节点 3创建跳表 4、计算节点排位 5、插入新节点 6、删除节点 总结 前言 跳跃表是Redis的底层数据结构之一...* * T = O(N) */ #define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */ #define ZSKIPLIST_MAXLEVEL 32...level : ZSKIPLIST_MAXLEVEL; } 2创建跳表节点 根据层数,分值和数据可以创建跳表节点,如下所示: /* * 创建一个层数为 level 的跳跃表节点, * 并将节点的成员对象设置为...创建跳表 初始化空跳表的函数如下,其中header节点是按照最大层数ZSKIPLIST_MAXLEVEL创建的: /* * 创建并返回一个新的跳跃表 * * T = O(1) */ zskiplist...obj ,分值为 score 的新节点, * 并将这个新节点插入到跳跃表 zsl

32640

你确定不来了解一下Redis跳跃表的原理吗

从该有序表搜索元素 ,需要比较的次数分别为 ,总共比较的次数为 2 + 4 + 6 = 12 次。有没有优化的算法吗?...跳表具有如下性质: (1) 由很多层结构组成 (2) 每一层都是一个有序的链表 (3) 最底层(Level 1)的链表包含所有元素 (4) 如果一个元素出现在 Level i 的链表,则它在 Level...例子:查找元素 117 (1) 比较 21, 比 21 大,往后面找 (2) 比较 37, 比 37大,比链表最大值小,从 37 的下面一层开始找 (3) 比较 71, 比 71 大,比链表最大值小...首先要在跳跃表定位到要删除的元素吧 我们知道该节点每一层都有前驱、后继指针,那么我们删除这个节点的时候,自然也要改变该节点的每一层节点指针的指向啦。...带着这个疑问我们看看源码吧!

1.6K20
领券