开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 27 天,点击查看活动详情
今天来学习下Go常见的习题问题(三十七),也是面试中可能会遇到的,让我们来一起学习吧~
链表
redis中的链表底层数据结构如下所示:
typedef struct listNode {
// 前置节点
struct listNode *prev;
// 后置节点
struct listNode *next;
// 节点的值
void *value;
} listNode;
紧接着会使用adlist.h/list
中的list来持有listNode节点,这样方便统计长度,以及匹配,释放等操作,相应的结构体如下所示:
typedef struct list {
// 表头节点
listNode *head;
// 表尾节点
listNode *tail;
// 链表所包含的节点数量
unsigned long len;
// 节点值复制函数
void *(*dup)(void *ptr);
// 节点值释放函数
void (*free)(void *ptr);
// 节点值对比函数
int (*match)(void *ptr, void *key);
} list;
dup
函数: 复制链表节点所保存的值free
函数: 释放链表节点所保存的值match
函数: 对比链表节点中的保存的值与传入的key值是否一致
redis的链表是一个双向链表,其中的特性如下:
- 双端队列: 因为链表节点有
prev
和next
指针, 获取当前某个链表节点的前置或者后置节点的复杂度为O(1)
- 无环链表: 因为链表的头节点的
prev
指针和表尾节点的next
指针都指向NULL
,所以遍历链表只要碰到NULL
即可结束 - 头指针和尾指针:通过链表中的
head
指针和tail
指针, 获取到链表的头结点或者尾结点的复杂度为O(1)
- 链表长度: 通过链表中的
len
属性,就可以轻松获取当前链表中的节点数量,复杂度为O(1)
- 多态属性: 链表中存在
void*
指针来保存节点值, 并且可以通过dup
、free
、match
三个方法来为节点设置特定的函数,这样就可以处理不同类型的值
总结
今天浅谈了Go的习题(三十七),参考资料《redis设计与实现》,接下来会继续分享其他的习题的相关知识,对于一个刚入门的我来说,还有许多地方需要学习,有错误的地方欢迎大家指出,共同进步!!