数据结构与对象-链表

        链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点灵活的改变链表的长度。
        作为一种常用的数据结构,链表内置在很多高级语言中。由于Redis使用的C语言中没有链表,所以Redis构建了自己的链表实现

链表和链表节点的实现

每个链表节点使用adlist.h/listNode结构来表示:

typedef struct listNode {
        //前置节点
        struct listNode *prev;
        //后置节点
        struct listNode *next;
        //节点的值
        void *value;
    }listNode;

多个listNode可以通过prev和next相连来组成链表,虽然这样就可以组成链表结构,但使用adlist.h/list来持有链表的话,操作会更加方便。

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;

list结构提供了表头指针和表尾指针,以及链表长度。而dup、free和match成员则是用来实现多态链表所需特定类型的函数:

  1. dup函数用于复制链表节点的值;
  2. free函数用于释放链表节点的值;
  3. match函数用于对比链表节点与另一输入的值是否相等;

Redis的链表实现的特性可以总结如下:

        双端:链表节点带有prev和next指针,获取某个节点的前置节点和后续节点的时间复杂度为O(1)。
        无环:表头节点的prev和表尾节点的next都指向null,对链表的访问总以null为终点。
        带有表头指针和表尾指针:通过list结构的head和tail指针,使得获取表头节点和表尾节点的时间复杂度为O(1)。
        带链表长度计数器:通过list结构的len属性来对list持有的节点数量计数,使得获取节点长度的时间复杂度为O(1)。
        多态:链表节点使用value指针保存节点的值,并且通过list结构的dup、free和match属性为节点值设置特定函数,使得节点可以保存不同类型的值。

链表和链表节点的API

函数作用时间复杂度
listSetDupMethod将给定函数设置为链表的节点值复制函数O(1),复制函数可以通过链表的dup属性
listGetDupMethod返回链表当前使用的节点值复制函数O(1)
listSetFreeMethod将给定函数设置为链表的节点值释放函数O(1),释放函数可以通过链表的free属性
listGetFree返回链表当前使用的节点值释放函数O(1)
listSetMatchMethod将给定函数设置为链表的节点值对比函数O(1),对比函数可以通过链表的match属性
listGetMatchMethod返回链表当前使用的节点值对比函数O(1)
listLength返回链表的长度(包含了多少个节点)O(1),链表长度可以通过链表的len属性直接获得
listFirst返回链表的表头节点O(1),表头节点可以通过链表的head属性直接获得
listLast返回链表的表尾节点O(1),表尾节点可以通过链表的tail属性直接获得
listPrevNode返回给定节点的前置节点O(1),前置节点可以通过节点的prev属性直接获得
listNextNode返回给定节点的后置节点O(1),后置节点可以通过节点的next属性直接获得
listNodeValue返回给定节点正在保存的值O(1),节点值可以通过节点的value属性直接获得
listCreate创建一个不包含任何节点的新链表O(1)
listAddNodeHead将一个包含给定值的新节点添加到给定链表的表头O(1)
listAddNodeTail将一个包含给定值的新节点添加到给定链表的表尾O(1)
listInsertNode将一个包含给定值的新节点添加到给定节点的之前或者之后O(1)
listSearchKey查找并返回链表中包含给定值的节点O(N),N为链表长度
listIndex返回链表在给定索引上的节点O(N),N为链表长度
listDelNode从链表中删除给定节点O(N),N为链表长度
listRotate将链表的表尾节点弹出,然后将弹出的节点插入到链表的表头,成为新的表头节点O(1)
listDup复制一个给定链表的副本O(N),N为链表长度
listRelease释放给定链表,以及链表中的所有节点O(N),N为链表长度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值