1.概述

链表是在程序设计过程中经常使用的数据结构,bcos系统内部的调度和tasklet的实现都是基于链表。所以,对链表的支持是bcos与生俱来的特性。bcos的链表设计参考了Linux内核链表的设计思想,如果用户想使用链表只需要在自己的数据结构中包含链表头,然后便可以开始使用链表来实现自己的数据结构了。

2.双向循环链表

下面展示了双向循环链表的所有接口并附有简单的解释。每个接口的参数都易于理解,读者很容易理解并使用接口实现利用双向循环链表进行数据的管理。

链表头:

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)

//动态初始化链表
static inline void INIT_LIST_HEAD(struct list_head *list)

链表节点的添加

//将新节点添加到head后面,如果head为链表头则将新节点添加到链表的最前面
static inline void list_add(struct list_head *new_, struct list_head *head)

//将新节点添加到head前面,如果head为链表头则将新节点添加到链表的最后面
static inline void list_add_tail(struct list_head *new_, struct list_head *head)

链表节点的删除

//将节点从链表中删除并将该节点的prev和next指针赋值为NULL
static inline void list_del(struct list_head *entry)

//将节点从链表中删除并将该节点的prev和next指针指向它自己
static inline void list_del_init(struct list_head *entry)

链表遍历

//从链表头遍历到链表尾
/**
 * list_for_each_entry_safe - iterate over list of given type safe against 
 * removal of list enty.
 * @pos:      the type * to use as a loop sursor.
 * @n:        another type * to use as temporary storage.
 * @head:     the head for your list.
 * @member:   the name of the list_struct within the strut.
 */
#define list_for_each_entry_safe(pos, n, head, member)

//从链表尾逆向遍历到链表头
/**
 * list_for_each_entry_safe_reverse
 * @pos:      the type *  to use as a loop cursor.
 * @n         another type * to use as temporary storage.
 * @head:     the head for your list.
 * @member:   the name of the list_struct within the struct.
 * 
 * Iterate backwards over list of given type, safe against removal
 * of list entry.
 */
#define list_for_each_entry_safe_reverse(pos, n, head,member)

获取链表的第一个节点

/**
 * list_first_entry - get the first element from a list.
 * @ptr:     the list head to take the element from.
 * @type:    the type of the struct this is embedded in.
 * @member:  the name of the list_struct within the struct.
 * 
 * Note, that list is expected to be not empty.
 */
#define list_first_entry(ptr, type, member)

判断是否是链表最后一个节点

/**
 * list_is_last - tests whether @list is the last entry in list @head
 * @list: the entry to test.
 * @head: the head of the list.
 */
static inline int list_is_last(const struct list_head *list,
        const struct list_head *head)

判断链表是否为空

/**
 * list_empty - tests whether a list is empty.
 * @head: the list to test.
 */
static inline int list_empty(const struct list_head *head)

以链表中某个元素为依据,升序的插入节点

/**
 * 在列表中升序插入,值更小的靠近链表头
 */
#define list_ascending_order_add(new_, pos, n, head, member, condition_member)

3.单向循环链表

单向循环链表的实现与双向循环链表类似,它的接口实现与双向循环链表也基本类似。接口如下:

链表头及初始化:

typedef struct slist_s {
	struct slist_s *next;
}slist_t;

//链表的静态初始化
#define SLIST_HEAD_INIT(name)	{&name}

//链表的动态初始化
static inline void slist_init_head(slist_t *head)

链表添加一个节点

//将新节点添加到head的后面
static inline void slist_add(slist_t *new_, slist_t *head)

链表删除节点:

//仅将节点从链表中移除,需要提供将被删除节点的上一个节点
static inline void slist_del(slist_t *prev, slist_t *node)

//将节点从链表中移除并初始化(将节点的next指针指向节点自己)
static inline void slist_del_init(slist_t *prev, slist_t *node)

判断节点是否是链表的最后一个节点

/*
 * list:被判断的链表节点
 * head:链表头
 */
static inline int slist_is_last(const slist_t *list, const slist_t *head)

判断链表是否为空

static inline int slist_empty(const slist_t *head)

对链表进行遍历

#define slist_for_each_entry_safe(pos, n, head, member)

单向循环链表的使用示例具体可以参考内存管理模块的实现。

Logo

更多推荐