QTAILQ队列数据结构

QTAILQ队列数据结构

这种数据结构由两种基本结构构成,分别是QTAILQ_ENTRY和QTAILQ_HEAD,前者表示队列的元素,后者表示队列的头。

#define QTAILQ_ENTRY(type)                                              \
union {                                                                 \
        struct type *tqe_next;        /* next element */                \
        QTailQLink tqe_circ;          /* link for circular backwards list */ \
}

typedef struct QTailQLink {
    void *tql_next;
    struct QTailQLink *tql_prev;
} QTailQLink;

entry为一个联合体类型,包含tqe_next和tqe_circ,前者适用于单向链表,后者适用于双向链表。

在构造单向链表时,tqe_next指向链表中的下一个元素。
在构造双向链表时,tqe_circ->tql_next指向链表中的下一个元素,tqe_circ->tql_prev指向链表中上一个元素的tqe_circ。

#define QTAILQ_HEAD(name, type)                                         \
union name {                                                            \
        struct type *tqh_first;       /* first element */               \
        QTailQLink tqh_circ;          /* link for circular backwards list */ \
}

head与entry结构类似,包含tqh_first和tqh_circ,前者适用于单向链表,后者适用于双向链表。

在构造单向链表时,tqh_first指向链表中的第一个元素。
在构造双向链表时,tqh_circ指向链表中的第一个元素的tqh_circ。

基于这些数据结构,有一些操作。

QTAILQ_INSERT_TAIL(head,elm,field)

#define QTAILQ_INSERT_TAIL(head, elm, field) do {                       \
        (elm)->field.tqe_next = NULL;                                   \
        (elm)->field.tqe_circ.tql_prev = (head)->tqh_circ.tql_prev;     \
        (head)->tqh_circ.tql_prev->tql_next = (elm);                    \
        (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;             \
} while (/*CONSTCOND*/0)

将新元素elm放入整个链表的最后一个。
最后一个元素的下一个元素肯定为NULL,所以(elm)->field.tqe_next = NULL;
最后一个元素的tqe_circ.tql_prev应该指向之前是最后一个元素的元素,即指向(head)->tqh_circ.tql_prev.
之前是最后一个元素的元素,即(head)->tqh_circ.tql_prev,的下一个元素,应该为elm,所以之前的最后一个元素->tql_next = (elm).
head的prev应该是elm,因此(head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ.

QTAILQ_INSERT_AFTER(head, listelm, elm, field)
向队列中的某元素后插入一个新的元素

QTAILQ_INSERT_BEFORE(listelm,elm,field)
向队列中的某元素前插入一个新的元素

posted @ 2021-02-24 12:54  EwanHai  阅读(576)  评论(0编辑  收藏  举报