net小伙曾在文章【数据结构】链式线性表的几种常用用法中写过关于线性表的操作方法,重新阅读发现代码很是稚嫩,现重新整理。

  一般情况下我们会使用一个结构体head来作为双向链表的头部,head有两个指针域,一个指向链表的开始,一个指向链表的末尾。双向链表的指针域也有两个,一个指向前一个节点,一个指向后一个节点。两个结构体定义如下:

 1 #define TAILQ_HEAD(name, type)          \
 2   struct name {                           \
 3       struct type *tqh_first; /* first element */      \
 4       struct type **tqh_last; /* addr of last next element */    \
 5   }   
 6 #define TAILQ_ENTRY(type)                       \
 7     struct {                                \
 8         struct type *tqe_next;  /* next element */          \
 9         struct type **tqe_prev; /* address of previous next element */  \
10     }

  使用二级指针是为了在遍历链表和删除链表的时候,代码更具有可读性。

  完整的链表拓扑如下:

【数据结构】——较规范的链表操作方法

  接下来直接给出代码,并附上一个小例子:

 1 #define TAILQ_HEAD(name, type)                  \
 2         struct name {                                                   \
 3                 struct type *tqh_first; /* first element */              \
 4                 struct type **tqh_last; /* addr of last next element */    \
 5         }
 6 #define TAILQ_ENTRY(type)                       \
 7         struct {                                \
 8                 struct type *tqe_next;  /* next element */          \
 9                 struct type **tqe_prev; /* address of previous next element */  \
10         }
11 
12 #define TAILQ_FIRST(head)   ((head)->tqh_first)
13 #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
14 #define TAILQ_EMPTY(head)   ((head)->tqh_first == NULL)
15 #define TRASHIT(x)  do {(x) = (void *)-1;} while (0)
16 
17 #define TAILQ_INIT(head) do {                       \
18         TAILQ_FIRST((head)) = NULL;                 \
19         (head)->tqh_last = &TAILQ_FIRST((head));            \
20 } while (0)
21 
22 #define TAILQ_INSERT_HEAD(head, elm, field) do {            \
23         if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)   \
24                 TAILQ_FIRST((head))->field.tqe_prev =           \
25                 &TAILQ_NEXT((elm), field);              \
26         else                                \
27                 (head)->tqh_last = &TAILQ_NEXT((elm), field);       \
28         TAILQ_FIRST((head)) = (elm);                    \
29         (elm)->field.tqe_prev = &TAILQ_FIRST((head));           \
30 } while (0)
31 
32 #define TAILQ_INSERT_TAIL(head, elm, field) do {            \
33         TAILQ_NEXT((elm), field) = NULL;                \
34         (elm)->field.tqe_prev = (head)->tqh_last;           \
35         *(head)->tqh_last = (elm);                  \
36         (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
37 } while (0)
38 
39 #define TAILQ_FOREACH(var, head, field)                 \
40         for ((var) = TAILQ_FIRST((head));               \
41                         (var);                          \
42                         (var) = TAILQ_NEXT((var), field))
43 
44 #define TAILQ_REMOVE(head, elm, field) do {             \
45         if ((TAILQ_NEXT((elm), field)) != NULL)             \
46                 TAILQ_NEXT((elm), field)->field.tqe_prev =      \
47                 (elm)->field.tqe_prev;              \
48         else {                              \
49                 (head)->tqh_last = (elm)->field.tqe_prev;       \
50         }                               \
51         *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);      \
52         TRASHIT((elm)->field.tqe_next);                 \
53         TRASHIT((elm)->field.tqe_prev);                 \
54 } while (0)
queue.h

相关文章:

  • 2021-07-06
  • 2021-08-01
  • 2022-01-11
  • 2021-11-17
  • 2022-12-23
  • 2021-08-18
  • 2021-08-28
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-25
  • 2021-10-01
  • 2021-12-26
  • 2021-09-05
相关资源
相似解决方案