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

Redis源码学习之链表

,pre指针指向其前置节点,next指针指向其后置节点,表头节点的pre属性和表尾节点的next属性为nil,节点值的类型为interface{},从而达到保存不同类型值的目的。...前置节点 next *listNode //后置节点 value interface{} //节点值 } 链表结构 通过list结构持有链表,其中head、tail属性分别指向表头和表尾节点...//持有链表结构 type list struct { //指向表头节点 head *listNode //指向表尾节点 tail *listNode //记录链表长度 length...属性以及表头、表尾属性的维护 if after { //插入节点到oldNode节点后,即oldNode.next = node node.pre = oldNode node.next =...<= 1 { return } //取出表尾 tail := l.tail l.tail = tail.pre l.tail.next = nil //将表尾插到表头 tail.next

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

    2、Redis数据结构——链表-linkedlist

    链表数据结构: typedef struct list { listNode *head; // 表头节点 listNode *tail; // 表尾节点 unsigned...; match函数则用于对比链表结点所保存的值和另一个输入值是否相等; 2、特性: 双端:链表结点带有prev和next指针,获取某个节点前置节点和后置节点复制度都是O(1) 无环:表头结点的prev指针和表尾结点的...带表头指针和表尾指针:获取表头节点和表尾节点复制度O(1) 带链表长度计数器:len属性对list持有的链表节点进行计数,获取节点数量复制度O(1) 多态:使用void* 指针保存节点值,通过list结构的...重点回顾 链表被广泛用于实现Redis各种功能,如列表键、发布订阅、慢查询等 每个链表结点由一个listNode结构来表示,每个节点都有一个指向前置节点和后置节点的指针,所以Redis的链表实现是双端链表...每个链表用一个list结构表示,这个结构带有表头节点指针、表尾节点指针以及链表长度等信息。 因为链表表头前置节点和表尾后置节点都指向NULL,所以Redis的链表实现是无环链表。

    37500

    2024重生之回溯数据结构与算法系列学习【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】

    对空表和非空表的处理需要用不同的代码逻辑 我们一般使用的都是带头结点的单链表 4.单链表的插入、删除 按位序插入(带头结点): ListInsert(&L,i,e): 插入操作,在表L中的第...i个位置上插入指定元素e 找到第i-1个结点,将新结点插入其后 若带有头结点,插入更加方便,头结点可以看作“第0个”结点,直接做上面的操作即可 若i插在表中则与插在表头一样进行操作,可以插入成功...r,每次插入都让r指向新的表尾结点,时间复杂度为O(n) 头插法: 每次插入元素都插入到单链表的表头 头插法和之前学过的单链表后插操作是一样的,可以直接套用 L->next=NULL;可以防止野指针...,时间复杂度为O(n) 如果需要频繁的访问表头、表尾,可以让L指向表尾元素(插入、删除时可能需要修改L) 从尾部找到头部,时间复杂度为O(1) 循环双链表的初始化: 循环双链表的初始化代码实现.../表头元素(后向/前向遍历的实现核心) 如何在表头、表中、表尾插入/删除一个结点 8.静态链表 什么是静态链表: 分配一整片连续的内存空间,各个结点集中安置 每个结点由两部分组成:data

    8210

    数据结构--顺序表

    一、引言 在计算机科学中,数据结构是一种存储和组织数据的方式,它使得数据的插入、删除和访问变得更加高效。...顺序表(Array List)是一种基本的数据结构,它在内存中连续存储元素,为我们提供了操作数据的一种简单而有效的方法。本文将介绍顺序表的基本概念、分类,并展示如何在C语言中实现动态顺序表。...二、顺序表的基本概念与结构 1.概念 顺序表(也称为线性表)是一种线性数据结构,其中元素按照顺序在内存中连续存储。它的主要特点包括: 连续存储:所有元素在内存中占据一块连续的空间。...固定大小:在静态实现中,顺序表的大小在创建时确定,无法动态调整。...x); //顺序表尾插 void SLPushBack(SL* p, DataType x); //顺序表头删 void SLDelHead(SL* p); //顺序表尾删 void SLDelBack

    16110

    Redis的双向链表一文全知道

    马上要开启爆更模式啦。在Redis中链表List的应用非常广泛,但是Redis是采用C语言来写,底层采用双向链表实现(这边提一嘴,如果是科班出身或者大学有学过数据结构的同学,可以划走啦)。...其为count,表示移除列表中与a相等的元素个数。即如果count>0,表示从表头开始向表尾搜索,移除count个与a相等的元素。...如果count表尾开始向表头搜索,移除count个与a相等的元素。如果count=0,移除所有与a相等的元素,因为是移除所有,所以不管从表头还是表尾,结果是一样的。 ​...每个节点都有两个指针,既能从表头根据尾指针找到表尾,又能从表尾根据头指针prev找到表头,如果将他们连起来,就构成了双向链表。 ​...的头指针和尾指针,最后针对list的往表头插入元素,往表尾插入元素,删除,修改等方法进行源码解析,使其对双向链表有更清晰的认识。

    2.2K30

    Redis 数据结构 skiplist

    结构则用于保存跳跃表节点的相关信息, 比如节点的数量, 以及指向表头节点和表尾节点的指针, 等等。...后退指针在程序从表尾向表头遍历时使用。 分值(score):各个节点中的 1.0 、 2.0 和 3.0 是节点所保存的分值。在跳跃表中,节点按各自所保存的分值从小到大排列。...图 5-3 用虚线表示出了程序从表头向表尾方向, 遍历跳跃表中所有节点的路径: 迭代程序首先访问跳跃表的第一个节点(表头), 然后从第四层的前进指针移动到表中的第二个节点。...// 表中节点的数量 unsigned long length; // 表中层数最大的节点的层数 int level; } zskiplist; header 和 tail 指针分别指向跳跃表的表头和表尾节点..., 通过这两个指针, 程序定位表头节点和表尾节点的复杂度为 O(1) 。

    44230

    《闲扯Redis十》Redis 跳跃表的结构实现

    结构则用于保存跳跃表节点的相关信息,比如节点的数量,以及指向表头节点和表尾节点的指针等。...后退指针在程序从表尾向表头遍历时使用。 分值(score):各个节点中的 1.0 、 2.0 和 3.0 是节点所保存的分值。在跳跃表中,节点按各自所保存的分值从小到大排列。...图 5-3 用虚线表示出了程序从表头向表尾方向,遍历跳跃表中所有节点的路径: ? 迭代程序首先访问跳跃表的第一个节点(表头), 然后从第四层的前进指针移动到表中的第二个节点。...header 和 tail 指针分别指向跳跃表的表头和表尾节点,通过这两个指针,程序定位表头节点和表尾节点的复杂度为 O(1) 。...通过跳跃表的表头节点和表尾节点, 这个检测可以用 O(1) 复杂度完成。 zslFirstInRange 给定一个分值范围, 返回跳跃表中第一个符合这个范围的节点。

    84320

    基础大扫荡——背包,栈,队列,链表一口气全弄懂

    提到数据结构,不得不说数据类型,有人将他们比作分子和原子的关系,我们都知道大自然最小的构成单位是原子,数据类型描述的是原子的内部,如质子、中子的情况,而数据结构是分子,由不同的原子以各种各样的结构组成。...在入列出列的操作过程中,front和rear的值会越来越大,这个大是没意义的,但会超过size值引发问题,所以我们要用相对位置, 1 front++ 改为 front = (front + 1) %...再重申一下这三种数据结构在存取顺序上,各自的关注点, 背包是不关注顺序,只存不取; 栈是只关注最顶部元素位置,支持存取; 队列是要同时关注队首和队尾两个位置,支持存取。...= node; 从表尾插入,稍微复杂一点,我们要先用循环找到表尾节点(表尾节点的特点是他的link为null),找到以后,将表尾节点的link从null修改为新增节点,然后新增节点的link设置为null...表头插入,表头取出,就实现了栈 表头取出,表尾插入,就实现了队列 背包只要插入,无所谓表头插入还是表尾插入。

    747150

    Redis数据结构:List类型全面解析

    在 Redis 中,列表最多可以包含 2^32 - 1 个元素。既可以支持正向检索和也可以支持反向检索。特征也与LinkedList类似:有序元素可重复插入和删除快查询速度一般。...,通过这个偏移量,可以确定表尾节点的地址 zllen uint16_t2字节一个 2 字节的整数,表示压缩列表中的节点数量。...LinkedList 结构为链表提供了表头指针 head、表尾指针 tail,以及节点数量计算 len。...O(1);无环:表头节点的 prev 指针和表尾节点的 next 指针都指向 NULL,对链表的访问以 NULL 为终点;表头指针/表尾指针:通过 list 结构的 head 指针和 tail 指针,...获取链表的表头节点和表尾节点的复杂度为 O(1);链表长度计数器:通过 list 结构的 len 属性来对 list 的链表节点进行计数,获取节点数量的复杂度为O(1);多态:链表节点使用 void*

    26810

    数据结构之循环队列C语言实现(详细)

    输入端称为队尾,输出端称为队头 因此,队列,又称为先进先出表(FIFO),类似于生活中的排队,先来的排在前头,后来的排在后头,一个一个办理业务。...那么在使用过程中,我们是从后面加入数据,从前面移除数据。那么随着出队和入队的进行,数组会整体向右平移,因为数组前面的元素因为出队变成了空白,变得不可使用。造成空间的浪费。...综上,我们使用循环队列,就是将队首和队尾黏在一起。类似于一个⚪; 那么知道了循环数组后,我们应该考虑下,队首和队尾怎么放置,才能使我们循环队列能够使用。...不同的队首和队尾的初始化,将导致我们判断队列是否已满以及队列是否为空的方法的不同。 (1)front(队首)和rear(队尾)初始化均为0。...另外,如何在代码实现过程中将正常数组变成循环数组呢?

    85430

    Redis面试(三):底层数据结构(二)

    、表尾节点 unsigned long length;// 表中节点数量 int level;// 表中层数最大的节点的层数 } zskiplisheader和tail指针分别指向跳跃表的表头和表尾节点...,通过这两个指针,程序定位表头节点和表尾节点的复杂度为O(1)。...节点的后退指针(backward属性)用于从表尾向表头方向访问节点跟可以一次跳过多个节点的前进指针不同,因为每个节点只有一个后退指针,所以每次只能后退至前一个节点。...level[i].forward:每个层都有一个指向表尾方向的前进指针(level[i].forward属性),用于从表头向表尾方向访问节点level[i].span:表示节点x在第i层到其下一个节点需跳过的节点数...建立公共溢出区(Overflow Area)将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表。这个溢出区可以是一个单独的数据结构,如链表或树。

    30940

    顺序表和链表

    但是在物理结构上并不一定是连续的, 线性表在物理上存储时,通常以数组和链式结构的形式存储 2.顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存...所以现实中基本都是使用动态顺序表,根据需要动态的分配空间 大小,所以下面我们实现动态顺序表。...* psl, SLDataType x); // 顺序表尾删 void SeqListPopBack(SeqList* psl); // 顺序表头插 void SeqListPushFront(...实际中更多是作为其他数据结 构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。 2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。...插入 动态顺序表,空间不够时需要 扩容 没有容量的概念 应用场景 元素高效存储+频繁访问 任意位置插入和删除频繁 缓存利用率 高 低 备注:缓存利用率参考存储体系结构 以及 局部原理性。

    6000

    什么是广义表

    强调一下,除非广义表为空表,否则广义表一定具有表头和表尾,且广义表的表尾一定是一个广义表。...例如在广义表中 LS={1,{1,2,3},5} 中,表头为原子 1,表尾为子表 {1,2,3} 和原子 5 构成的广义表,即 {{1,2,3},5}。...再比如,在广义表 LS = {1} 中,表头为原子 1 ,但由于广义表中无表尾元素,因此该表的表尾是一个空表,用 {} 表示。...广义表的复制详解(含C语言代码实现) 对于任意一个非空广义表来说,都是由两部分组成:表头和表尾。反之, 只要确定的一个广义表的表头和表尾,那么这个广义表就可以唯一确定下来。...复制一个广义表,也是不断的复制表头和表尾的过程。如果表头或者表尾同样是一个广义表,依旧复制其表头和表尾。 所以,复制广义表的过程,其实就是不断的递归,复制广义表中表头和表尾的过程。

    11410

    Redis的设计与实现(4)-跳跃表

    跨度用来计算排位 (rank) : 在查找某个节点的过程中, 将沿途访问过的所有层的跨度累计起来, 得到的结果就是目标节点在跳跃表中的排位. 1.4 后退指针 节点的后退指针 (backward) 用于从表尾向表头方向访问节点...跳跃表 使用一个 zskiplist 结构来持有节点, 可以更方便地访问跳跃表的表头节点和表尾节点, 又或者快速地获取跳跃表节点 的数量 (也即是跳跃表的长度) 等信息. zskiplist 结构的定义如下...; // 表中节点的数量 unsigned long length; // 表中层数最大的节点的层数 int level; } zskiplist; header 和 tail 指针分别指向跳跃表的表头和表尾节点..., 程序定位表头节点和表尾节点的复杂度为 O(1) . length 属性记录节点的数量, 可在 O(1) 复杂度内返回跳跃表的长度. level 则用于在 O(1) 复杂度内获取跳跃表中层高最大的那个节点的层数量...通过跳跃表的表头节点和表尾节点, 这个检测可以用 O(1) 复杂度完成. zslFirstInRange 给定一个分值范围, 返回跳跃表中第一个符合这个范围的节点.

    37310

    5、Redis数据结构——跳跃表-skiplist

    ,比如节点数量,以及表头节点和表尾节点的指针等。...后退指针用于表尾向表头遍历使用。 3)分值:在跳跃表中,节点按照各自所保存的分值从小到大排列。 4)成员对象:各个节点的o1、o2等是节点所保存的成员对象。...: 仅靠多个跳跃表节点就可以组成一个跳跃表 但通过使用一个zskiplist结构来持有这些节点,程序可以更加方便地对整个跳跃表进行处理,比如快速访问跳跃表的表头节点和表尾节点,或者快速获取跳跃表节点的数量...typedef struct zskiplist { //表头节点和表尾节点 struct zskiplistNode *header, *tail; //表中节点的的数量 unsigned long...length; //表中层数最大的节点层数 int level; } zskiplist; header和tail指针分别指向跳跃表的表头和表尾节点,通过这两个指针,程序定位表头和表尾节点的复杂度为

    43330

    Redis的设计与实现(2)-链表

    len 分别是表头表尾指针和节点数量, 而 dup, free 和 match 则是用于实现多态链表所需的类型特定函数: dup 函数用于复制链表节点所保存的值; free 函数用于释放链表节点所保存的值...将链表的表尾节点弹出, 然后将被弹出的节点插入到链表的表头, 成为新的表头节点 O(1) listDup 复制一个给定链表的副本 O(N), N 为链表长度 listRelease 释放给定链表, 以及链表中的所有节点...总结 双端: 节点带有 prev 和 next 指针, 获取其前置和后置节点的复杂度都是 O(1); 无环: 表头节点的 prev 指针和表尾节点的 next 指针都指向 NULL, 对链表的访问以 NULL...为终点; 带表头指针和表尾指针: 通过 list 结构的 head 指针和 tail 指针, 获取表头和表尾节点的复杂度为 O(1); 带链表长度计数器: 通过 list 结构的 len 属性, 程序获取链表中节点数量的复杂度为..., 所以 Redis 的链表实现是双端链表; 每个链表使用一个 list 结构来表示, 这个结构带有表头节点指针, 表尾节点指针, 以及链表长度等信息; 因为链表表头节点的前置节点和表尾节点的后置节点都指向

    15510

    链表第一课

    此外,我们还需要两个变量,分别指向链表的头节点和尾节点:本文使用first变量指向头节点,last变量指向尾节点。 下面介绍四个链表的操作: 创建第一个节点。 在表头添加节点。 在表尾添加节点。...在表头删除节点。 创建第一个节点 创建第一个节点非常容易,只需要新建一个节点,并将变量first和last都指向这个节点即可: ?...它还是第一个节点,所以last和first变量都指向它。 这个节点的item变量被赋值为boy,这是我们希望存储的数据。...在表尾添加节点 在表尾添加节点和在表头添加节点非常相似,过程如下: 将oldlast变量指向尾节点; 新建一个节点并将last变量指向他; 将oldlast变量所指节点的next变量指向新节点。 ?...链表一个典型的应用是在栈(LIFO)和队列(FIFO)中,栈使用后进先出的策略,在表头添加节点,在表头删除节点;队列使用先进先出的策略,在表头添加节点,在表尾删除节点。

    32230
    领券