链表结点中保存两个指针,分别指向前后,还有一个void *指针指向保存的数据
typedef struct listNode {
struct listNode *prev;
struct listNode *next;
void *value;
} listNode;
链表,包含两个链表节点指针,一个指向head,一个指向tail
其中dup函数指针指向两个链表拷贝时对链表节点value的拷贝方法。
match为寻找链表中和key相同的value时的比较方法。
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;
还有一个链表迭代器,在函数中访问,遍历链表都是通过迭代器完成。
direction为标志为前向迭代器还是反向迭代器。
typedef struct listIter {
listNode *next;
int direction;
} listIter;
#define AL_START_HEAD 0//前向
#define AL_START_TAIL 1//反向
通过定义宏来完成链表中函数指针的赋值以及或许一些信息
#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)
创建链表
list *listCreate(void);
所有成员均为空
清空链表
释放链表中所有的链表节点。但是并不释放链表本身
void listEmpty(list *list);
删除链表
清空,将本身也释放
void listRelease(list *list)
{
listEmpty(list);
zfree(list);
}
从头添加节点
list *listAddNodeHead(list *list, void *value);
从尾添加节点
list *listAddNodeTail(list *list, void *value);
插入节点
after表示在其给定节点的前面插入还是后面插入
list *listInsertNode(list *list, listNode *old_node, void *value, int after);
获取前向迭代器
void listRewind(list *list, listIter *li) {//正向
li->next = list->head;
li->direction = AL_START_HEAD;
}
函数内部通过迭代器遍历链表
listNode *listNext(listIter *iter)
{
listNode *current = iter->next;
if (current != NULL) {
if (iter->direction == AL_START_HEAD)
iter->next = current->next;
else
iter->next = current->prev;
}
return current;
}
通过索引访问元素,其中index为0表示head,-1表示tail
listNode *listIndex(list *list, long index) {
listNode *n;
if (index < 0) {
index = (-index)-1;
n = list->tail;
while(index-- && n) n = n->prev;
} else {
n = list->head;
while(index-- && n) n = n->next;
}
return n;
}
根据key值查找
listNode *listSearchKey(list *list, void *key)
{
listIter iter;
listNode *node;
listRewind(list, &iter);
while((node = listNext(&iter)) != NULL) {
if (list->match) {
if (list->match(node->value, key)) {
return node;
}
} else {
if (key == node->value) {
return node;
}
}
}
return NULL;
}