我是靠谱客的博主 虚心柠檬,最近开发中收集的这篇文章主要介绍双向链表,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文中的代码都来至wpa_supplicant_0.7.2srcutilslist.h,学习并做了点注释


双向链表的操作代码:

/**
 * struct dl_list - Doubly-linked list
 */
struct dl_list {
struct dl_list *next;
struct dl_list *prev;
};


static inline void dl_list_init(struct dl_list *list)
{
list->next = list;
list->prev = list;
}


static inline void dl_list_add(struct dl_list *list, struct dl_list *item)
{
item->next = list->next;
item->prev = list;
list->next->prev = item;
list->next = item;
}


static inline void dl_list_add_tail(struct dl_list *list, struct dl_list *item)
{
dl_list_add(list->prev, item);
}


static inline void dl_list_del(struct dl_list *item)
{
item->next->prev = item->prev;
item->prev->next = item->next;
item->next = NULL;
item->prev = NULL;
}


static inline int dl_list_empty(struct dl_list *list)
{
return list->next == list;
}


static inline unsigned int dl_list_len(struct dl_list *list)
{
struct dl_list *item;
int count = 0;
for (item = list->next; item != list; item = item->next)
count++;
return count;
}

// 获取当前成员变量在其结构体中的偏移量
/*
(long)&((type *)p->member) - (long)(type *)p;
把P换成0,不知道这样是否好理解~
*/

#ifndef offsetof
#define offsetof(type, member) ((long) &((type *) 0)->member)
#endif


// 已知结构体中某个成员变量的地址,根据其偏移地址获得该结构体的起始地址
#define dl_list_entry(item, type, member) 
((type *) ((char *) item - offsetof(type, member)))


// 取双向链表的第一个节点
#define dl_list_first(list, type, member) 
(dl_list_empty((list)) ? NULL : 
dl_list_entry((list)->next, type, member))


// 取双向链表的最后一个节点
#define dl_list_last(list, type, member) 
(dl_list_empty((list)) ? NULL : 
dl_list_entry((list)->prev, type, member))


// 顺序遍历所有节点
#define dl_list_for_each(item, list, type, member) 
for (item = dl_list_entry((list)->next, type, member); 
    &item->member != (list); 
    item = dl_list_entry(item->member.next, type, member))


//该宏函数与上面的dl_list_for_each相比就是多了个缓存变量n用于存放当前所取节点的下一个节点,可用于循环遍历的时候对当前节点进行删除操作
#define dl_list_for_each_safe(item, n, list, type, member) 
for (item = dl_list_entry((list)->next, type, member), 
    n = dl_list_entry(item->member.next, type, member); 
    &item->member != (list); 
    item = n, n = dl_list_entry(n->member.next, type, member))


// 逆向遍历所有节点
#define dl_list_for_each_safe(item, n, list, type, member) 
for (item = dl_list_entry((list)->next, type, member), 
    n = dl_list_entry(item->member.next, type, member); 
    &item->member != (list); 
    item = n, n = dl_list_entry(n->member.next, type, member))


最后

以上就是虚心柠檬为你收集整理的双向链表的全部内容,希望文章能够帮你解决双向链表所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部