tips:本文参照《redis设计与实现》、《数据结构与算法》、redis源码
链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活调整链表的长度。
因为redis使用C语言并没有内置这种数据结构,所以redis构建了自己的链表实现。
adlist.h/listNode
typedef struct listNode {
//前置节点
struct listNode *prev;
//后置节点
struct listNode *next;
//节点值
void *value;
} listNode;
多个listNode通过prev、next组成双端列表,如下图
虽然仅仅使用多个listNode就可以组成链表,但使用adlist.h/list来持有链表的话,操作起来更方便,尤其是对head与tail操作(实际过程中这两操作非常频繁)
typedef struct list {
//表头节点
listNode *head;
//表尾节点
listNode *tail;
//节点复制函数
void *(*dup)(void *ptr);
//节点释放函数
void (*free)(void *ptr);
//节点值对比函数
int (*match)(void *ptr, void *key);
//节点数量
unsigned long len;
} list;
接下来看下有3个listNode组成的list结构的链表
redis链表实现总结:
1)双端:链表节点都带有prev和next指针,获取某个节点的前置、后置节点的复杂度都是 O(1)
2) 无环,表头节点的prev指针和表尾节点的tail指针都指向null,对链表的访问以null为终点
3)拥有head和tail,通过list结构,程序获取链表的表头节点、表尾节点时间复杂度O(1)
4)带链表长度计数器,程序获取链表的节点数量时间复杂度为O(1)
链表和链表节点的API
网友评论