关于双链表实现,一般教科书上定义一个双向链表节点的方法如下:
struct list_node{
stuct list_node *pre;
stuct list_node *next;
ElemType data;
}
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name){&(name),&(name)}
#define LIST_HEAD(name)
struct list_head name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) do {
(ptr)->next = (ptr); (ptr)->prev = (ptr);
} while (0)
LIST_HEAD(mylist);
与
struct list_head mylist;
INIT_LIST_HEAD(&mylist);
插入操作
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
//在头节点后面插入一个节点
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
//在尾节点后插入一个节点
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
}
static inline void list_replace(struct list_head *old,
struct list_head *new)
{
new->next = old->next;
new->next->prev = new;
new->prev = old->prev;
new->prev->next = new;
}
#define list_entry(ptr, type, member) container_of(ptr, type, member)
//container_of宏的定义如下:
#define container_of(ptr, type, member)({
const typeof(((type *)0)->member ) *__mptr = (ptr);
(type *)( (char *)__mptr - offsetof(type,member) );})
//offsetof的宏定义如下:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
将上述简化一下成为下面这样:
#define list_entry(ptr, type, member)
((type *)((char *)(ptr)-(size_t)(&((type *)0)->member)))
#define list_for_each(pos, head)
for(pos = (head)->next, prefetch(pos->next);pos!=(head);
pos = pos->next,prefetch(pos->next))
#define list_for_each_entry(pos, head, member)
for(pos = list_entry((head)->next, typeof(*pos), member);
prefetch(pos->member.next), &pos->member != (head);
pos = list_entry(pos->member.next, typeof(*pos), member))
struct mystruct{
ElemType1 data1;
ElemType2 data2;
strcut list_head anchor;//通常我们称结构体内的链表节点为链表锚,因为它有定位的作用。
}
struct mystruct *pos;
list_for_each_entry(pos,head,anchor){
mystruct *pStruct=pos;
//do something with pStruct.....
}
list_for_each_prev(pos, head)
list_for_each_prev_safe(pos, n, head)
list_for_each_entry_reverse(pos, head, member)
list_prepare_entry(pos, head, member)
static inline int list_empty_careful(const struct list_head *head)
static inline void list_del_init(struct list_head *entry)
static inline void list_move(struct list_head *list, struct list_head *head)
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
static inline int list_empty(const struct list_head *head)