欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

redis系列之------链表

程序员文章站 2022-05-18 20:24:01
前言 链表提供了高效的节点重排能力, 以及顺序性的节点访问方式, 并且可以通过增删节点来灵活地调整链表的长度。 作为一种常用数据结构, 链表内置在很多高级的编程语言里面, 因为 Redis 使用的 C 语言并没有内置这种数据结构, 所以 Redis 构建了自己的链表实现。 大家可以把Redis的链表 ......

前言

链表提供了高效的节点重排能力, 以及顺序性的节点访问方式, 并且可以通过增删节点来灵活地调整链表的长度。

作为一种常用数据结构, 链表内置在很多高级的编程语言里面, 因为 redis 使用的 c 语言并没有内置这种数据结构, 所以 redis 构建了自己的链表实现。

大家可以把redis的链表实现,和java的linkedlist实现进行对比,看下哪个更加厉害一点。

 

链表定义

 1 typedef struct listnode {
 2 
 3     // 前置节点
 4     struct listnode *prev;
 5 
 6     // 后置节点
 7     struct listnode *next;
 8 
 9     // 节点的值
10     void *value;
11 
12 } listnode;

 

多个 listnode 可以通过 prev 和 next 指针组成双端链表, 如图 3-1 所示。

redis系列之------链表

虽然仅仅使用多个 listnode 结构就可以组成链表, 但使用 adlist.h/list 来持有链表的话, 操作起来会更方便:

 

 1 typedef struct list {
 2 
 3     // 表头节点
 4     listnode *head;
 5 
 6     // 表尾节点
 7     listnode *tail;
 8 
 9     // 链表所包含的节点数量
10     unsigned long len;
11 
12     // 节点值复制函数
13     void *(*dup)(void *ptr);
14 
15     // 节点值释放函数
16     void (*free)(void *ptr);
17 
18     // 节点值对比函数
19     int (*match)(void *ptr, void *key);

 

redis系列之------链表

 

我们可以看到,list包含链表的头节点,尾节点以及长度。这就为链表带来了很多的好处,如下:

  • 双端: 链表节点带有 prev 和 next 指针, 获取某个节点的前置节点和后置节点的复杂度都是 o(1) 。
  • 无环: 表头节点的 prev 指针和表尾节点的 next 指针都指向 null , 对链表的访问以 null 为终点。
  • 带表头指针和表尾指针: 通过 list 结构的 head 指针和 tail 指针, 程序获取链表的表头节点和表尾节点的复杂度为 o(1) 。
  • 带链表长度计数器: 程序使用 list 结构的 len 属性来对 list 持有的链表节点进行计数, 程序获取链表中节点数量的复杂度为 o(1)。