源码笔记2.双端链表adlist

数据结构

// 链表节点结构
typedef struct listNode {
    // 前置节点
    struct listNode *prev;
    // 后置节点
    struct listNode *next;
    // 节点值
    void *value;
} listNode;

链表节点包含前置和后置节点的指针。

// 链表结构
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;

链表结构包含头结点指针、尾结点指针、链表长度,以及三个函数指针(复制dup、释放free、match)。

方法列表
listCreate 创建一个新链表。
listRelease 释放整个链表。
listAddNodeHead 添加一个节点到链表头。
listAddNodeTail 添加一个节点到链表尾。
listInsertNode 在指定位置插入一个节点。
listDelNode 删除指定节点。
listGetIterator 给指定链表创建一个迭代器。

// 迭代器结构
typedef struct listIter {
    // 当前迭代到的节点
    listNode *next;
    // 迭代的方向
    int direction;
} listIter;

listReleaseIterator 释放迭代器。
listRewind 将迭代器的方向设置为从头到尾,并重新指向表头。
listRewindTail 将迭代器的方向设置为从尾到头,并重新指向表尾。
listNext 返回迭代器的下个元素(直接返回iter->next,如果不为NULL,再把next指向下一个节点)。
listDup 复制链表。

流程是创建一个空链表,然后用迭代器遍历原链表,将每个节点值依次添加到新的链表尾部。

// 拷贝值的代码块
// copy是新链表,dup是原链表dup函数的指针
if (copy->dup) 
{
    value = copy->dup(node->value); // 如果设置了复制函数,就调用复制函数去复制value
    if (value == NULL) // value复制失败,链表复制失败。
    {
    	listRelease(copy);
    	listReleaseIterator(iter);
    	return NULL;
    }
}
// 如果没有设置dup函数,直接赋值。
else
    //注意这里value是void*指针,直接赋值后,新链表节点和原链表节点指向同一个值。
    value = node->value;

listSearchKey 查找指定的值。

流程是用迭代器遍历链表,将每个节点值做比较。

// 比较值的代码块
// list是链表,match是匹配函数
if (list->match)
{
    if (list->match(node->value, key)) // 如果设置了match函数,使用match的
    {
        listReleaseIterator(iter);
        return node;
    }
}
// 没有设置match
else
{
    // 直接对比指针
    if (key == node->value)
    {
        listReleaseIterator(iter);
        // 找到
        return node;
    }
}

listIndex 返回链表指定位置的节点。(index可以是负数,从后向前)
listRotate 将表尾节点取出,插到表头。

总结:
双端链表的经典实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值