1. 链表和链表节点的实现
//adlist.h
typedef struct listNode {
struct listNode *prev;//节点前向指针
struct listNode *next;//节点后向指针
void *value;//节点的值 无类型指针
} listNode;
//adlist.h
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;
特点:
- 双向
- 无环,表头节点的prev指向NULL,表尾节点的next指向NULL
- 带表头指针和表尾指针,获取首尾节点的时间为O(1)
- len记录链表长度,获取链表长度的时间为O(1)
- 多态,value的类型为void *, 可以保存多种节点类型值
typedef struct listNode{
void *value;
}listNode;
int main() {
listNode node;
int x=1;
double y=1.0;
node.value=&x;
printf("%d\n",*(int *)(node.value));
node.value=&y;
printf("%f\n",*(double *)(node.value));
return 0;
}
2. 常用API
3. 总结
- 链表被广泛用于实现Redis的各种功能,比如列表键、发布与订阅、慢查询、监视器等
- 每个链表节点由一个listNode结构来表示,每个节点都有一个指向前置节点和后置节点的指针,所以Redis的链表实现是双端链表
- 每个链表使用一个list结构来表示,这个结构带有表头节点指针、表尾节点指针,以及链表长度等信息
- 因为链表表头节点的前置节点和表尾节点的后置节点都指向NULL,所以Redis的链表实现是无环链表
- 通过为链表设置不同的类型特定函数,Redis的链表可以用于保存各种不同类型的值