各种链表队列的宏操作及应用

来源:互联网 发布:连汝安 知乎 编辑:程序博客网 时间:2024/05/16 01:35

链表队列的宏操作参考自libevent,这种链表的宏操作非常容易移植,现在我将它记录下来。所有例子的代码请前往各种链表队列宏操作的应用例子免积分下载。

Singly-linked List


/* * Singly-linked List definitions. */#define SLIST_HEAD(name, type)\struct name {\struct type *slh_first;/* first element */\}#defineSLIST_HEAD_INITIALIZER(head)\{ NULL }#ifndef WIN32#define SLIST_ENTRY(type)\struct {\struct type *sle_next;/* next element */\}#endif/* * Singly-linked List access methods. */#defineSLIST_FIRST(head)((head)->slh_first)#defineSLIST_END(head)NULL#defineSLIST_EMPTY(head)(SLIST_FIRST(head) == SLIST_END(head))#defineSLIST_NEXT(elm, field)((elm)->field.sle_next)#defineSLIST_FOREACH(var, head, field)\for((var) = SLIST_FIRST(head);\    (var) != SLIST_END(head);\    (var) = SLIST_NEXT(var, field))/* * Singly-linked List functions. */#defineSLIST_INIT(head) {\SLIST_FIRST(head) = SLIST_END(head);\}#defineSLIST_INSERT_AFTER(slistelm, elm, field) do {\(elm)->field.sle_next = (slistelm)->field.sle_next;\(slistelm)->field.sle_next = (elm);\} while (0)#defineSLIST_INSERT_HEAD(head, elm, field) do {\(elm)->field.sle_next = (head)->slh_first;\(head)->slh_first = (elm);\} while (0)#defineSLIST_REMOVE_HEAD(head, field) do {\(head)->slh_first = (head)->slh_first->field.sle_next;\} while (0)

示意图如下,我用visio软件简单的画了下载。



写了一个简单的应用。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include "queue.h"#define SIZEOF(array)    (sizeof(array)/sizeof(array[0]))struct student{    SLIST_ENTRY(student) next;    char name[16];    int score;};static struct stu{    char name[16];    int score;}stuArray[]={        {"Yancy Lin",88},        {"Tom Lee",89},        {"Rose Li",100},        {"Thomas Ye",58},        {"Rick Huang",79},        {"Nike Wong",65},};int main() {    int i;    SLIST_HEAD(headname,student) head;    SLIST_INIT(&head);  //  SLIST_HEAD(headname,student) head=SLIST_HEAD_INITIALIZER(head);    /**     * 或者使用下面声明初始化,一次性搞定     * SLIST_HEAD(headname,student) head=SLIST_HEAD_INITIALIZER(head);     */    struct student * tmp;    /* 往head链表里添加一node节点 */    for(i=0;i<SIZEOF(stuArray);i++)    {        tmp = (struct student *)malloc(sizeof(struct student));        memcpy(tmp->name,stuArray[i].name,strlen(stuArray[i].name));        tmp->score = stuArray[i].score;        SLIST_INSERT_HEAD(&head,tmp,next);//往链表头部添加节点node    }    printf("traversing Singly-linked List using SLIST_FOREACH:\n");    /* 遍历链表 */    SLIST_FOREACH(tmp,&head,next)    {        printf("%s:%d\n",tmp->name,tmp->score);    }    printf("\n");    printf("freeing Singly-linked List using SLIST_REMOVE_HEAD:\n");    /* 释放node */    while ((tmp = SLIST_FIRST(&head))) {        SLIST_REMOVE_HEAD(&head,next);        printf("%s:%d\n",tmp->name,tmp->score);        free(tmp);    }    return 0;}



List

/* * List definitions. */#define LIST_HEAD(name, type)\struct name {\struct type *lh_first;/* first element */\}#define LIST_HEAD_INITIALIZER(head)\{ NULL }#define LIST_ENTRY(type)\struct {\struct type *le_next;/* next element */\struct type **le_prev;/* address of previous next element */\}/* * List access methods */#defineLIST_FIRST(head)((head)->lh_first)#defineLIST_END(head)NULL#defineLIST_EMPTY(head)(LIST_FIRST(head) == LIST_END(head))#defineLIST_NEXT(elm, field)((elm)->field.le_next)#define LIST_FOREACH(var, head, field)\for((var) = LIST_FIRST(head);\    (var)!= LIST_END(head);\    (var) = LIST_NEXT(var, field))/* * List functions. */#defineLIST_INIT(head) do {\LIST_FIRST(head) = LIST_END(head);\} while (0)#define LIST_INSERT_AFTER(listelm, elm, field) do {\if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)\(listelm)->field.le_next->field.le_prev =\    &(elm)->field.le_next;\(listelm)->field.le_next = (elm);\(elm)->field.le_prev = &(listelm)->field.le_next;\} while (0)#defineLIST_INSERT_BEFORE(listelm, elm, field) do {\(elm)->field.le_prev = (listelm)->field.le_prev;\(elm)->field.le_next = (listelm);\*(listelm)->field.le_prev = (elm);\(listelm)->field.le_prev = &(elm)->field.le_next;\} while (0)#define LIST_INSERT_HEAD(head, elm, field) do {\if (((elm)->field.le_next = (head)->lh_first) != NULL)\(head)->lh_first->field.le_prev = &(elm)->field.le_next;\(head)->lh_first = (elm);\(elm)->field.le_prev = &(head)->lh_first;\} while (0)#define LIST_REMOVE(elm, field) do {\if ((elm)->field.le_next != NULL)\(elm)->field.le_next->field.le_prev =\    (elm)->field.le_prev;\*(elm)->field.le_prev = (elm)->field.le_next;\} while (0)#define LIST_REPLACE(elm, elm2, field) do {\if (((elm2)->field.le_next = (elm)->field.le_next) != NULL)\(elm2)->field.le_next->field.le_prev =\    &(elm2)->field.le_next;\(elm2)->field.le_prev = (elm)->field.le_prev;\*(elm2)->field.le_prev = (elm2);\} while (0)

示意图如下:



示例代码就不粘贴了,请在开头我所说的地址下载就行了。

Simple queue


/* * Simple queue definitions. */#define SIMPLEQ_HEAD(name, type)\struct name {\struct type *sqh_first;/* first element */\struct type **sqh_last;/* addr of last next element */\}#define SIMPLEQ_HEAD_INITIALIZER(head)\{ NULL, &(head).sqh_first }#define SIMPLEQ_ENTRY(type)\struct {\struct type *sqe_next;/* next element */\}/* * Simple queue access methods. */#defineSIMPLEQ_FIRST(head)    ((head)->sqh_first)#defineSIMPLEQ_END(head)    NULL#defineSIMPLEQ_EMPTY(head)    (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))#defineSIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)#define SIMPLEQ_FOREACH(var, head, field)\for((var) = SIMPLEQ_FIRST(head);\    (var) != SIMPLEQ_END(head);\    (var) = SIMPLEQ_NEXT(var, field))/* * Simple queue functions. */#defineSIMPLEQ_INIT(head) do {\(head)->sqh_first = NULL;\(head)->sqh_last = &(head)->sqh_first;\} while (0)#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {\if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)\(head)->sqh_last = &(elm)->field.sqe_next;\(head)->sqh_first = (elm);\} while (0)#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {\(elm)->field.sqe_next = NULL;\*(head)->sqh_last = (elm);\(head)->sqh_last = &(elm)->field.sqe_next;\} while (0)#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {\if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\(head)->sqh_last = &(elm)->field.sqe_next;\(listelm)->field.sqe_next = (elm);\} while (0)#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do {\if (((head)->sqh_first = (elm)->field.sqe_next) == NULL)\(head)->sqh_last = &(head)->sqh_first;\} while (0)

示意图如下:



示例代码就不粘贴了,请在开头我所说的地址下载就行了。


Tail queue

/* * Tail queue definitions. */#define TAILQ_HEAD(name, type)\struct name {\struct type *tqh_first;/* first element */\struct type **tqh_last;/* addr of last next element */\}#define TAILQ_HEAD_INITIALIZER(head)\{ NULL, &(head).tqh_first }#define TAILQ_ENTRY(type)\struct {\struct type *tqe_next;/* next element */\struct type **tqe_prev;/* address of previous next element */\}/* * tail queue access methods */#defineTAILQ_FIRST(head)((head)->tqh_first)#defineTAILQ_END(head)NULL#defineTAILQ_NEXT(elm, field)((elm)->field.tqe_next)#define TAILQ_LAST(head, headname)\(*(((struct headname *)((head)->tqh_last))->tqh_last))/* XXX */#define TAILQ_PREV(elm, headname, field)\(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))#defineTAILQ_EMPTY(head)\(TAILQ_FIRST(head) == TAILQ_END(head))#define TAILQ_FOREACH(var, head, field)\for((var) = TAILQ_FIRST(head);\    (var) != TAILQ_END(head);\    (var) = TAILQ_NEXT(var, field))#define TAILQ_FOREACH_REVERSE(var, head, headname, field)\for((var) = TAILQ_LAST(head, headname);\    (var) != TAILQ_END(head);\    (var) = TAILQ_PREV(var, headname, field))/* * Tail queue functions. */#defineTAILQ_INIT(head) do {\(head)->tqh_first = NULL;\(head)->tqh_last = &(head)->tqh_first;\} while (0)#define TAILQ_INSERT_HEAD(head, elm, field) do {\if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)\(head)->tqh_first->field.tqe_prev =\    &(elm)->field.tqe_next;\else\(head)->tqh_last = &(elm)->field.tqe_next;\(head)->tqh_first = (elm);\(elm)->field.tqe_prev = &(head)->tqh_first;\} while (0)#define TAILQ_INSERT_TAIL(head, elm, field) do {\(elm)->field.tqe_next = NULL;\(elm)->field.tqe_prev = (head)->tqh_last;\*(head)->tqh_last = (elm);\(head)->tqh_last = &(elm)->field.tqe_next;\} while (0)#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {\if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\(elm)->field.tqe_next->field.tqe_prev =\    &(elm)->field.tqe_next;\else\(head)->tqh_last = &(elm)->field.tqe_next;\(listelm)->field.tqe_next = (elm);\(elm)->field.tqe_prev = &(listelm)->field.tqe_next;\} while (0)#defineTAILQ_INSERT_BEFORE(listelm, elm, field) do {\(elm)->field.tqe_prev = (listelm)->field.tqe_prev;\(elm)->field.tqe_next = (listelm);\*(listelm)->field.tqe_prev = (elm);\(listelm)->field.tqe_prev = &(elm)->field.tqe_next;\} while (0)#define TAILQ_REMOVE(head, elm, field) do {\if (((elm)->field.tqe_next) != NULL)\(elm)->field.tqe_next->field.tqe_prev =\    (elm)->field.tqe_prev;\else\(head)->tqh_last = (elm)->field.tqe_prev;\*(elm)->field.tqe_prev = (elm)->field.tqe_next;\} while (0)#define TAILQ_REPLACE(head, elm, elm2, field) do {\if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL)\(elm2)->field.tqe_next->field.tqe_prev =\    &(elm2)->field.tqe_next;\else\(head)->tqh_last = &(elm2)->field.tqe_next;\(elm2)->field.tqe_prev = (elm)->field.tqe_prev;\*(elm2)->field.tqe_prev = (elm2);\} while (0)

示意图如下:


示例代码就不粘贴了,请在开头我所说的地址下载就行了。

Circular queue



/* * Circular queue definitions. */#define CIRCLEQ_HEAD(name, type)\struct name {\struct type *cqh_first;/* first element */\struct type *cqh_last;/* last element */\}#define CIRCLEQ_HEAD_INITIALIZER(head)\{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }#define CIRCLEQ_ENTRY(type)\struct {\struct type *cqe_next;/* next element */\struct type *cqe_prev;/* previous element */\}/* * Circular queue access methods */#defineCIRCLEQ_FIRST(head)((head)->cqh_first)#defineCIRCLEQ_LAST(head)((head)->cqh_last)#defineCIRCLEQ_END(head)((void *)(head))#defineCIRCLEQ_NEXT(elm, field)((elm)->field.cqe_next)#defineCIRCLEQ_PREV(elm, field)((elm)->field.cqe_prev)#defineCIRCLEQ_EMPTY(head)\(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))#define CIRCLEQ_FOREACH(var, head, field)\for((var) = CIRCLEQ_FIRST(head);\    (var) != CIRCLEQ_END(head);\    (var) = CIRCLEQ_NEXT(var, field))#define CIRCLEQ_FOREACH_REVERSE(var, head, field)\for((var) = CIRCLEQ_LAST(head);\    (var) != CIRCLEQ_END(head);\    (var) = CIRCLEQ_PREV(var, field))/* * Circular queue functions. */#defineCIRCLEQ_INIT(head) do {\(head)->cqh_first = CIRCLEQ_END(head);\(head)->cqh_last = CIRCLEQ_END(head);\} while (0)#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {\(elm)->field.cqe_next = (listelm)->field.cqe_next;\(elm)->field.cqe_prev = (listelm);\if ((listelm)->field.cqe_next == CIRCLEQ_END(head))\(head)->cqh_last = (elm);\else\(listelm)->field.cqe_next->field.cqe_prev = (elm);\(listelm)->field.cqe_next = (elm);\} while (0)#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {\(elm)->field.cqe_next = (listelm);\(elm)->field.cqe_prev = (listelm)->field.cqe_prev;\if ((listelm)->field.cqe_prev == CIRCLEQ_END(head))\(head)->cqh_first = (elm);\else\(listelm)->field.cqe_prev->field.cqe_next = (elm);\(listelm)->field.cqe_prev = (elm);\} while (0)#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {\(elm)->field.cqe_next = (head)->cqh_first;\(elm)->field.cqe_prev = CIRCLEQ_END(head);\if ((head)->cqh_last == CIRCLEQ_END(head))\(head)->cqh_last = (elm);\else\(head)->cqh_first->field.cqe_prev = (elm);\(head)->cqh_first = (elm);\} while (0)#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {\(elm)->field.cqe_next = CIRCLEQ_END(head);\(elm)->field.cqe_prev = (head)->cqh_last;\if ((head)->cqh_first == CIRCLEQ_END(head))\(head)->cqh_first = (elm);\else\(head)->cqh_last->field.cqe_next = (elm);\(head)->cqh_last = (elm);\} while (0)#defineCIRCLEQ_REMOVE(head, elm, field) do {\if ((elm)->field.cqe_next == CIRCLEQ_END(head))\(head)->cqh_last = (elm)->field.cqe_prev;\else\(elm)->field.cqe_next->field.cqe_prev =\    (elm)->field.cqe_prev;\if ((elm)->field.cqe_prev == CIRCLEQ_END(head))\(head)->cqh_first = (elm)->field.cqe_next;\else\(elm)->field.cqe_prev->field.cqe_next =\    (elm)->field.cqe_next;\} while (0)#define CIRCLEQ_REPLACE(head, elm, elm2, field) do {\if (((elm2)->field.cqe_next = (elm)->field.cqe_next) ==\    CIRCLEQ_END(head))\(head).cqh_last = (elm2);\else\(elm2)->field.cqe_next->field.cqe_prev = (elm2);\if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) ==\    CIRCLEQ_END(head))\(head).cqh_first = (elm2);\else\(elm2)->field.cqe_prev->field.cqe_next = (elm2);\} while (0)


示意图如下:



示例代码就不粘贴了,请在开头我所说的地址下载就行了。


原创粉丝点击