链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活的调整链表的长度
链表在Redis中的应用非常广泛,例如列表键的底层实现之一就是链表、哈希键的底层实现之一也使用了哈希表+链表等。除了上述两种,发布订阅、慢查询、监视器等功能也用到了链表,本身还使用了链表来保存多个客户端的状态信息,已经使用链表来构建客户端输出缓存区(output buffer)。
本篇主要对Redis中链表节点及链表的结构总结介绍、以及其特性。
链表和链表节点的实现
链表节点结构如下:
typedef struct listNode {
// 前置节点
struct listNode *prev;
// 后置节点
struct listNode *next;
// 节点的值
void * value;
} listNode;
而整个链表的实现为 双向链表即double linkedList,多个listNode通过prev和next指针连接组成双端链表。整个结构如下图所示:

typedef struct list {
// 表头节点
listNode *head;
// 表尾节点
listNode *tail;
// 链表所包含的节点数量
unsigned long len;
// 节点值复制函数
void *(*dup) (void *ptr)
// 节点值释放函数
void *(*free) (void *ptr)
// 节点值对比函数
void *(*match) (void *ptr)
}
注:list结构为链表提供了表头指针head、表尾指针tail及链表长度len,同时dup、free、match成员则是用于实现多态链表所需的类型特定函数。
链表实现的特性
由链表的属性和链表节点的属性决定其特性:
- 双端:由于prev和next指针的存在,获取某个节点的前置节点和后置节点的时间复杂度均为O(1)。
- 无环:表头的节点prev指针和表尾节点的next指针都指向null。
- 头尾:通过head指针和tail指针获取表头节点和表尾节点的时间复杂度为 O(1)。
- 长度:通过属性len,获取链表长度时间复杂度为 O(1),并且增加减少节点修改len值即可。
- 多态:链表节点使用 void *指针来保存节点值,并可以通过list结构的dup、free、match属性为节点值设置类型特定的函数,所有可以保存不同类型的值!!!
Over~~~~~~~