Redis设计与实现笔记(二) | 链表结构

没错,本篇我们要说一说链表在Redis中的应用。本打算写Redis中的列表,但想来想去觉得列表仅仅是Redis链表的一部分,并不能完全说明链表这一数据结构在Redis中的应用。那就说说数据结构链表吧。小伙伴们,开始啦!

注:链表作为列表的底层实现是有条件的。当列表元素数量较多,或者是元素都是特别长的字符串时,才会使用链表作为列表的底层实现;当元素数量特别少,并且元素是特别短的字符串或者是特别小的整型数字时,将使用压缩列表来作为列表的底层实现。如图所示:

列表中的数据结构示意图

2.1 数据结构:链表

C语言中没有内置这种数据结构(例如Java实现了链表结构 LinkedList),所以Redis需要自己实现链表结构。链表是一种基本的数据结构,就不再详细的说明了。那对于Redis的链表是怎么实现的呢?

2.1.1  链表节点

Redis中的链表节点是怎么实现的呢?每一个链表节点都是使用 ListNode  结构体实现的,ListNode 结构体定义在adlist.h 头文件中。定义如下:

typedef struct ListNode{
    // 前(后)置节点
    struct ListNode *prev;
    struct ListNode *next;
    // 值
    void *value;
}ListNode;

由上述定义可知:

  • Redis中链表是一个双向链,每一个节点都指向前后节点。
  • 每个节点值的类型都是void,可知节点可以保存任意类型的值。也就是说,一个链表中可以保存不同类型的数据。

由多个ListNode组成的链表结构,如下图所示:

                 

站在链表结构上来讲,多个节点已经可以组成一个基本的链表了,但对于操作来说,还是需要一些其他信息来管理这个链表。这些信息包括链表长度、头(尾)节点、判断两个节点是否相等、释放节点空间、复制节点,上图仅仅由ListNode 组成的链表无法方便的完成。(注意:“无法方便的完成” 是指可以通过复杂的操作完成,就是复杂、不方便)

2.1.2  list结构体

由于仅仅由ListNode组成的链表不易管理,使用list来持有链表,那么,操作起来就easy多了。list结构体定义在adlist.h中,定义如下:

typedef struct list{
    // 节点头、尾、链表长度
    ListNode *head;
    ListNode *tail;
    unsigned int  len;
    // 复制节点、释放节点、对比节点
    void *(*dup)(void *ptr);
    void *(*free)(void *prt);
    int *(*match)(void *ptr,void *key);
    
}

由上述定义可知:

  • 获取链表长度的复杂度O(1),无需遍历整个链表
  • 获取头尾节点的复杂度O(1)

还有一条就是链表是无环的

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值