【BSD数据库】SLIST | STAILQ | LIST | TAILQ

BSD Library

#include 

1.SLIST 单链列表

SLIST_HEAD结构体声明:

SLIST_HEAD(HEADNAME, TYPE) head;

其中HEADNAME是要定义的结构的名称,TYPE是要链接到列表中的元素。指向列表头部的指针可以随后声明为:

struct HEADNAME *headp;

Singly-linked list example:


SLIST_HEAD(slisthead, entry) head = SLIST_HEAD_INITIALIZER(head);
struct slisthead *headp;                /* Singly-linked List
                                      head. */
struct entry {
   ...
   SLIST_ENTRY(entry) entries;     /* Singly-linked List. */
   ...
} *n1, *n2, *n3, *np;

SLIST_INIT(&head);                      /* Initialize the list. */

n1 = malloc(sizeof(struct entry));      /* Insert at the head. */
SLIST_INSERT_HEAD(&head, n1, entries);

n2 = malloc(sizeof(struct entry));      /* Insert after. */
SLIST_INSERT_AFTER(n1, n2, entries);

SLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */
free(n2);

n3 = SLIST_FIRST(&head);
SLIST_REMOVE_HEAD(&head, entries);      /* Deletion from the head. */
free(n3);
                                   /* Forward traversal. */
SLIST_FOREACH(np, &head, entries)
   np-> ...

while (!SLIST_EMPTY(&head)) {           /* List Deletion. */
   n1 = SLIST_FIRST(&head);
   SLIST_REMOVE_HEAD(&head, entries);
   free(n1);
}

2.LIST 列表

LIST_HEAD结构体声明:

LIST_HEAD(HEADNAME, TYPE) head;

其中HEADNAME是要定义的结构的名称,TYPE是要链接到列表中的元素。指向列表头部的指针稍后可以声明为:

struct HEADNAME *headp;

List example:

LIST_HEAD(listhead, entry) head =
LIST_HEAD_INITIALIZER(head);
struct listhead *headp;                 /* List head. */
struct entry {
    ...
	LIST_ENTRY(entry) entries;      /* List. */
    ...
} *n1, *n2, *n3, *np, *np_temp;

LIST_INIT(&head);                       /* Initialize the list. */

n1 = malloc(sizeof(struct entry));      /* Insert at the head. */
LIST_INSERT_HEAD(&head, n1, entries);

n2 = malloc(sizeof(struct entry));      /* Insert after. */
LIST_INSERT_AFTER(n1, n2, entries);

n3 = malloc(sizeof(struct entry));      /* Insert before. */
LIST_INSERT_BEFORE(n2, n3, entries);

LIST_REMOVE(n2, entries);               /* Deletion. */
free(n2);
                                    /* Forward traversal. */
LIST_FOREACH(np, &head, entries)
    np-> ...

while (!LIST_EMPTY(&head)) {            /* List Deletion. */
    n1 = LIST_FIRST(&head);
    LIST_REMOVE(n1, entries);
    free(n1);
}

n1 = LIST_FIRST(&head);                 /* Faster List Deletion. */
while (n1 != NULL) {
    n2 = LIST_NEXT(n1, entries);
    free(n1);
    n1 = n2;
}
LIST_INIT(&head);

3.STAILQ 单链尾队列

STAILQ_HEAD 结构体声明:

STAILQ_HEAD(HEADNAME, TYPE) head;

其中HEADNAME是要定义的结构的名称,TYPE是要链接到尾队列的元素。指向尾部头部的指针队列稍后可以声明为:

struct HEADNAME *headp;

Singly-linked tail queue example:

STAILQ_HEAD(stailhead, entry) head =STAILQ_HEAD_INITIALIZER(head);
struct stailhead *headp;                /* Singly-linked tail queue head. */
struct entry {
   ...
   STAILQ_ENTRY(entry) entries;    /* Tail queue. */
   ...
} *n1, *n2, *n3, *np;

STAILQ_INIT(&head);                     /* Initialize the queue. */

n1 = malloc(sizeof(struct entry));      /* Insert at the head. */
STAILQ_INSERT_HEAD(&head, n1, entries);

n1 = malloc(sizeof(struct entry));      /* Insert at the tail. */
STAILQ_INSERT_TAIL(&head, n1, entries);

n2 = malloc(sizeof(struct entry));      /* Insert after. */
STAILQ_INSERT_AFTER(&head, n1, n2, entries);
                                   /* Deletion. */
STAILQ_REMOVE(&head, n2, entry, entries);
free(n2);
                                   /* Deletion from the head. */
n3 = STAILQ_FIRST(&head);
STAILQ_REMOVE_HEAD(&head, entries);
free(n3);
                                   /* Forward traversal. */
STAILQ_FOREACH(np, &head, entries)
   np-> ...
                                   /* TailQ Deletion. */
while (!STAILQ_EMPTY(&head)) {
   n1 = STAILQ_FIRST(&head);
   STAILQ_REMOVE_HEAD(&head, entries);
   free(n1);
}
STAILQ_INIT(&head);

4.TAILQ 尾队列

TAILQ_HEAD结构体声明:

TAILQ_HEAD(HEADNAME, TYPE) head;

其中HEADNAME是要定义的结构的名称,TYPE是要链接到尾队列中的元素。指向尾部头部的指针队列稍后可以声明为:

struct HEADNAME *headp;

Tail queue example:

TAILQ_HEAD(tailhead, entry) head = TAILQ_HEAD_INITIALIZER(head);
struct tailhead *headp;                 /* Tail queue head. */
struct entry {
 	...
 	TAILQ_ENTRY(entry) entries;     /* Tail queue. */
 	...
} *n1, *n2, *n3, *np;

TAILQ_INIT(&head);                      /* Initialize the queue. */

n1 = malloc(sizeof(struct entry));      /* Insert at the head. */
TAILQ_INSERT_HEAD(&head, n1, entries);

n1 = malloc(sizeof(struct entry));      /* Insert at the tail. */
TAILQ_INSERT_TAIL(&head, n1, entries);

n2 = malloc(sizeof(struct entry));      /* Insert after. */
TAILQ_INSERT_AFTER(&head, n1, n2, entries);

n3 = malloc(sizeof(struct entry));      /* Insert before. */
TAILQ_INSERT_BEFORE(n2, n3, entries);

TAILQ_REMOVE(&head, n2, entries);       /* Deletion. */
free(n2);
                                 /* Forward traversal. */
TAILQ_FOREACH(np, &head, entries)
 np-> ...
                                 /* Reverse traversal. */
TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries)
 np-> ...
                                 /* TailQ Deletion. */
while (!TAILQ_EMPTY(&head)) {
 n1 = TAILQ_FIRST(&head);
 TAILQ_REMOVE(&head, n1, entries);
 free(n1);
}
                                 /* Faster TailQ Deletion. */
n1 = TAILQ_FIRST(&head);
while (n1 != NULL) {
 n2 = TAILQ_NEXT(n1, entries);
 free(n1);
 n1 = n2;
}


TAILQ_INIT(&head);
n2 = malloc(sizeof(struct entry));  /* Insert before. */
CIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
                             /* Forward traversal. */
for (np = head.cqh_first; np != (void *)&head;
 np = np->entries.cqe_next)
np-> ...
                             /* Reverse traversal. */
for (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev)
np-> ...
                             /* Delete. */
while (head.cqh_first != (void *)&head)
CIRCLEQ_REMOVE(&head, head.cqh_first, entries);

TAILQ_CONCAT(TAILQ_HEAD *head1, TAILQ_HEAD *head2, TAILQ_ENTRY NAME);

TAILQ_EMPTY(TAILQ_HEAD *head);

TAILQ_ENTRY(TYPE);

TAILQ_FIRST(TAILQ_HEAD *head);

TAILQ_FOREACH(TYPE *var, TAILQ_HEAD *head, TAILQ_ENTRY NAME);

TAILQ_FOREACH_REVERSE(TYPE *var, TAILQ_HEAD *head, HEADNAME, TAILQ_ENTRY NAME);

TAILQ_HEAD(HEADNAME, TYPE);

TAILQ_HEAD_INITIALIZER(TAILQ_HEAD head);

TAILQ_INIT(TAILQ_HEAD *head);

TAILQ_INSERT_AFTER(TAILQ_HEAD *head, TYPE *listelm, TYPE *elm, TAILQ_ENTRY NAME);

TAILQ_INSERT_BEFORE(TYPE *listelm, TYPE *elm, TAILQ_ENTRY NAME);

TAILQ_INSERT_HEAD(TAILQ_HEAD *head, TYPE *elm, TAILQ_ENTRY NAME);

TAILQ_INSERT_TAIL(TAILQ_HEAD *head, TYPE *elm, TAILQ_ENTRY NAME);

TAILQ_LAST(TAILQ_HEAD *head, HEADNAME);

TAILQ_NEXT(TYPE *elm, TAILQ_ENTRY NAME);

TAILQ_PREV(TYPE *elm, HEADNAME, TAILQ_ENTRY NAME);

TAILQ_REMOVE(TAILQ_HEAD *head, TYPE *elm, TAILQ_ENTRY NAME);

TAILQ_SWAP(TAILQ_HEAD *head1, TAILQ_HEAD *head2, TYPE, TAILQ_ENTRY NAME);

结构体

TAILQ_ENTERY

  • TAILQ对指向前后两个元素指针的抽象
  • 描述前一个和下一个元素的结构体
#define TAILQ_ENTERY(type) \
struct {\
	struct type *tqe_next; /* 下一个元素*/ \
	struct type **tqe_prev; /*上一节点的下一个元素地址*/ \
	TRACEBUF\
\}

TAILQ_HEAD

  • TAILQ把整个队列头单独抽象为结构体
#define TAILQ_HEAD(name, type) \
struct name {\
	struct type *tqh_first; /* first element */\
	struct type **tqh_last; /* addr of last next element */\
	TRACEBUF\
\}

TAILQ队列常用操作

  • 初始化队列:TAILQ_INIT
  • 遍历队列:TAILQ_FOREACH
  • 检查队列是否为空:TAILQ_EMPTY
  • 在指定元素之前插入元素:TAILQ_INSERT_BEFORE
  • 在指定元素之后插入元素:TAILQ_INSERT_AFTER
  • 在队尾插入元素:TAILQ_INSERT_TAIL
  • 从队列中移除元素:TAILQ_REMOVE

TAILQ_INIT

#define TAILQ_INIT(head) do {\
    TAILQ_FIRST((head)) = NULL;\
    (head)->tqh_last = &TAILQ_FIRST((head));\
    QMD_TRACE_HEAD(head);\
} while (0)

TAILQ_FIRST

  • 队列中的第一个元素
#define TAILQ_FIRST(head) ((head)->tqh_first)

TAILQ_NEXT

  • 当前元素的下一个元素
#define TAILQ_NEXT(elm,field) ((elm)->field.tqe_next)

TAILQ_FOREACH

#define TAILQ_FOREACH(var,head,field) \
for (var = TAILQ_FIRST(heade); var; var = TAILQ_NEXT(var,field))

你可能感兴趣的:(c库,list,算法)