数据结构的应用--Adlist.h定义

1.节点结构

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

2.双向链表结构

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;

3.双向链表遍历器

typedef struct listIter {
    listNode *next;   //下一个节点
    int direction;
} listIter;

方向定义

#define AL_START_HEAD 0  //向前查找
   #define AL_START_TAIL 1    //向后查找

4.宏定义函数

#define listLength(l) ((l)->len)
#define listFirst(l) ((l)->head)
#define listLast(l) ((l)->tail)
#define listPrevNode(n) ((n)->prev)
#define listNextNode(n) ((n)->next)
#define listNodeValue(n) ((n)->value)

#define listSetDupMethod(l,m) ((l)->dup = (m))
#define listSetFreeMethod(l,m) ((l)->free = (m))
#define listSetMatchMethod(l,m) ((l)->match = (m))

#define listGetDupMethod(l) ((l)->dup)
#define listGetFree(l) ((l)->free)
#define listGetMatchMethod(l) ((l)->match)

5.定义函数

list *listCreate(void); //创建一个新的链表。该链表可以使用AlFree()方法释放。

//但使用AlFree()方法前需要释放用户释放私有节点的值。

//如果没有创建成功,返回null;创建成功则返回指向新链表的指针。

void listRelease(list *list);  //释放整个链表,此函数不会执行失败。调用zfree(list *list)方法,定义在Zmalloc.c中。

list *listAddNodeHead(list *list, void *value); //向链表头部中增加一个节点

list *listAddNodeTail(list *list, void *value);    //向链表尾部增加一个节点

list *listInsertNode(list *list, listNode *old_node, void *value, int after);//向某个节点位置插入节点 after为方向

void listDelNode(list *list, listNode *node);//从链表上删除特定节点,调用者释放特定私用节点的值。

//该函数不会执行失败
listIter *listGetIterator(list *list, int direction);//返回某个链表的迭代器。

//迭代器的listNext()方法会返回链表的下个节点。direction是方向

//该函数不会执行失败。

listNode *listNext(listIter *iter);

void listReleaseIterator(listIter *iter);            //释放迭代器的内存。

list *listDup(list *orig);                               //复制整个链表。当内存溢出时返回null,成功时返回原链表的一个备份

//不管该方法是否执行成功,原链表不会改变。

listNode *listSearchKey(list *list, void *key);  //从特定的链表查找key。成功则返回第一个匹配节点的指针

//如果没有匹配,则返回null。

listNode *listIndex(list *list, long index);     //序号从0开始,链表的头的索引为0.1为头节点的下个节点。一次类推。

//负整数用来表示从尾部开始计数。-1表示最后一个节点,-2倒数第二个节点

//如果超过链表的索引,则返回null

void listRewind(list *list, listIter *li) {
    li->next = list->head;
    li->direction = AL_START_HEAD;
}

void listRewindTail(list *list, listIter *li) {
    li->next = list->tail;
    li->direction = AL_START_TAIL;
}

void listRotate(list *list);                 //旋转链表,移除尾节点并插入头部。

深入redis内部--实现双向链表的更多相关文章

  1. 关于redis内部的数据结构

    最大感受,无论从设计还是源码,Redis都尽量做到简单,其中运用到的原理也通俗易懂.特别是源码,简洁易读,真正做到clean and clear, 这篇文章以unstable分支的源码为基准,先从大体 ...

  2. redis内部数据结构深入浅出

    最大感受,无论从设计还是源码,Redis都尽量做到简单,其中运用到的原理也通俗易懂.特别是源码,简洁易读,真正做到clean and clear, 这篇文章以unstable分支的源码为基准,先从大体 ...

  3. 探索Redis设计与实现6:Redis内部数据结构详解——skiplist

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  4. 探索Redis设计与实现5:Redis内部数据结构详解——quicklist

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  5. 探索Redis设计与实现4:Redis内部数据结构详解——ziplist

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  6. 【转】Redis内部数据结构详解——ziplist

    本文是<Redis内部数据结构详解>系列的第四篇.在本文中,我们首先介绍一个新的Redis内部数据结构--ziplist,然后在文章后半部分我们会讨论一下在robj, dict和zipli ...

  7. 【转】Redis内部数据结构详解 -- skiplist

    本文是<Redis内部数据结构详解>系列的第六篇.在本文中,我们围绕一个Redis的内部数据结构--skiplist展开讨论. Redis里面使用skiplist是为了实现sorted s ...

  8. redisbook笔记——redis内部数据结构

    在Redis的内部,数据结构类型值由高效的数据结构和算法进行支持,并且在Redis自身的构建当中,也大量用到了这些数据结构. 这一部分将对Redis内存所使用的数据结构和算法进行介绍. 动态字符串 S ...

  9. [转]Redis内部数据结构详解-sds

    本文是<Redis内部数据结构详解>系列的第二篇,讲述Redis中使用最多的一个基础数据结构:sds. 不管在哪门编程语言当中,字符串都几乎是使用最多的数据结构.sds正是在Redis中被 ...

随机推荐

  1. UVA 11426 GCD - Extreme (II)(欧拉函数打表 + 规律)

    Given the value of N, you will have to find the value of G. The definition of G is given below:Here ...

  2. Android Activity 无法获取组件尺寸

    Activity 创建的时候,可能在 onCreate 的时刻,窗口 Window 对象的创建还未完成. 那么最合适的时机是什么呢?答案是:onWindowFocusChanged.这个方法在 Act ...

  3. python网络编程--线程的方法,线程池

    一.线程的其他方法(Thread其他属性和方法) ident() 获取线程id Thread实例对象的方法 isAlive() 设置线程名 getName() 返回线程名 setName() 设置线程 ...

  4. pandas iterrows()

    按照行遍历,第一个是行索引,第二个是每一行,series类型.

  5. 常用类(日期时间格式转换,date,枚举)

    1 常用类 1.1 日期时间类 计算机如何表示时间? 时间戳(timestamp):距离特定时间的时间间隔. 计算机时间戳是指距离历元(1970-01-01 00:00:00:000)的时间间隔(ms ...

  6. NOI2019省选模拟赛 第三场

    传送门 明明没参加过却因为点进去结果狂掉\(rating\)-- \(A\) 集合 如果我们记 \[f_k=\sum_{i=1}^nT^i{n-i\choose k}\] 那么答案显然就是\(f_{k ...

  7. Java Web 学习与总结(一)Servlet基础

    配置环境:https://www.cnblogs.com/qq965921539/p/9821374.html 简介: Servlet是Sun公司提供的一种实现动态网页的解决方案,在制定J2EE时引入 ...

  8. [转] LVM分区在线扩容

    [转] LVM分区在线扩容 在线扩容的这台服务器,LV分区格式为xfs,原大小1.2TB.增加了一块硬盘,大小为1.8TB. fdisk /dev/cciss/c0d1 # 创建分区,并指定分区类型为 ...

  9. String 源码浅析————终结篇

    写在前面 说说这几天看源码的感受吧,其实 jdk 中的源码设计是最值得进阶学习的地方.我们在对 api 较为熟悉之后,完全可以去尝试阅读一些 jdk 源码,打开 jdk 源码后,如果你英文能力稍微过得 ...

  10. python 爬虫入门之爬小说

    ##第一步 导包from bs4 import BeautifulSoupimport requestsimport sys ##准备class downloder(object): def __in ...