双链表

#ifndef __LIST_H__
#define __LIST_H__


#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
#ifndef container_of
#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})
#endif

struct dList {
         struct dList *next, *prev;
};

//当我们知道dList的地址时,可以通过list_entry这个宏获取它的父结构的地址。
//所以这个宏的功能就是由结构体成员的地址求结构体的地址。其中ptr是所求结构体中
//dList成员的指针,type是所求结构体的类型,member是结构体dList成员名
#define dlist_entry(ptr, type, member) \
         container_of(ptr, type, member)

#define LIST_HEAD_INIT(name) { &(name), &(name) }

//生成名字为name的双向链表的头节点
#define LIST_HEAD(name) \
    struct dList name = LIST_HEAD_INIT(name)

//初始化链表头
static inline void INIT_LIST_HEAD(struct dList *list)
{
        //链表的前一个节点和后一个节点都指向它自己
        list->next = list;
        list->prev = list;
}

static inline void __list_add(struct dList *_new, struct dList *prev, struct dList *next)
{
        next->prev = _new;
        _new->next = next;
        _new->prev = prev;
        prev->next = _new;
}
//双向链表插入节点的操作---在头节点head的下一个节点,即是头插
static inline void dlist_add(struct dList *_new, struct dList *head)
{
        __list_add(_new, head, head->next);
}

//双向链表插入节点的操作---向尾部插入_new节点
static inline void dlist_add_tail(struct dList *_new, struct dList *head)
{
    __list_add(_new, head->prev, head);
}

//判断链表是不是空的,如果空返回真,否则返回假
//也就是判断表头的节点的下一个节点是不是它本身
static inline int dlist_empty(const struct dList *head)
{
    return head->next == head;
}

//获取双向链表的第一个节点
static inline struct dList* dlist_get_first(struct dList *head)
{
    if (!head)
    {
        return NULL;
    }

    if (dlist_empty(head))
    {
        return NULL;
    }

    return head->next;
}

//获取双向链表的尾节点
static inline struct dList* dlist_get_tail(struct dList *head)
{
    if (!head)
    {
        return NULL;
    }

    if (dlist_empty(head))
    {
        return NULL;
    }

    return head->prev;
}

static inline void __list_del(struct dList * prev, struct dList * next)
{
        next->prev = prev;
        prev->next = next;
}

//双向链表中节点删除 ,并把被删除的位置清0
static inline void dlist_del(struct dList *entry)
{
        __list_del(entry->prev, entry->next);
        entry->next = NULL;
        entry->prev = NULL;
}
static inline void __list_del_entry(struct dList *entry)
{
    __list_del(entry->prev, entry->next);
}
//将上面entry被删除的节点重新初始化
static inline void dlist_del_init(struct dList *entry)
{
    __list_del_entry(entry);
    INIT_LIST_HEAD(entry);
}

//将老的节点old换成新的节点_new
static inline void dlist_replace(struct dList *old,
                struct dList *_new)
{
    _new->next = old->next;
    _new->next->prev = _new;
    _new->prev = old->prev;
    _new->prev->next = _new;
}
//将上面的过程进行重新初始化
static inline void dlist_replace_init(struct dList *old,
                    struct dList *_new)
{
    dlist_replace(old, _new);
    INIT_LIST_HEAD(old);
}

//将链表中的list节点移动到链表的头部
static inline void dlist_move(struct dList *list, struct dList *head)
{
    __list_del_entry(list);
    dlist_add(list, head);
}

//判断当前链表list节点是不是链表的最后一个节点
static inline int dlist_is_last(const struct dList *list,
                const struct dList *head)
{
    return list->next == head;
}

//判断链表是不是空的,如果空返回真,否则返回假 ,稍微和上面有区别的是
//判断表头的前一个节点和后一个节点是否为本身,是返回真,不是,返回假
//也就是prev和next
static inline int dlist_empty_careful(const struct dList *head)
{
    struct dList *next = head->next;
    return (next == head) && (next == head->prev);
}

/**
 * list_move_tail - delete from one list and add as another's tail
 * @list: the entry to move
 * @head: the head that will follow our entry
 */
static inline void dlist_move_tail(struct dList *list,
                  struct dList *head)
{
        __list_del(list->prev, list->next);
        dlist_add_tail(list, head);
}

//将链表进行翻转,也就是将head的next和head的本身做交换
static inline void dlist_rotate_left(struct dList *head)
{
    struct dList *first;

    if (!dlist_empty(head)) {
        first = head->next;
        dlist_move_tail(first, head);
    }
}

//判断链表中是否只有一个节点
static inline int dlist_is_singular(const struct dList *head)
{
    return !dlist_empty(head) && (head->next == head->prev);
}

static inline void __list_cut_position(struct dList *list,
        struct dList *head, struct dList *entry)
{
    struct dList *_new_first = entry->next;
    list->next = head->next;
    list->next->prev = list;
    list->prev = entry;
    entry->next = list;
    head->next = _new_first;
    _new_first->prev = head;
}

//分割链表,以entry为界限进行分割,分割完后的另一半的那条链表被list所指
static inline void dlist_cut_position(struct dList *list,
        struct dList *head, struct dList *entry)
{
    if (dlist_empty(head))
        return;
    if (dlist_is_singular(head) &&
        (head->next != entry && head != entry))
        return;
    if (entry == head)
        INIT_LIST_HEAD(list);
    else
        __list_cut_position(list, head, entry);
}

static inline void __list_splice(const struct dList *list,
                 struct dList *prev,
                 struct dList *next)
{
    struct dList *first = list->next;
    struct dList *last = list->prev;

    first->prev = prev;
    prev->next = first;

    last->next = next;
    next->prev = last;
}

//将list和head这两条链表合并,注意,链表不能为空
static inline void dlist_splice(const struct dList *list,
                struct dList *head)
{
    if (!dlist_empty(list))
        __list_splice(list, head, head->next);
}

//将list和head这两条链表合并后并初始化
static inline void dlist_splice_init(struct dList *list,
                    struct dList *head)
{
    if (!dlist_empty(list)) {
        __list_splice(list, head, head->next);
        INIT_LIST_HEAD(list);
    }
}



#define prefetch(x) __builtin_prefetch(x)

//双向链表的正向遍历,从前往后
#define dlist_for_each(pos, head) \
         for (pos = (head)->next; prefetch(pos->next), pos != (head); \
                 pos = pos->next)

//双向链表的遍历,跟上面那个有所不同的是,下面这个添加了通过list_entry,方便很多
#define dlist_for_each_entry(pos, head, member)				\
    for (pos = dlist_entry((head)->next, typeof(*pos), member);	\
         &pos->member != (head); 	\
         pos = dlist_entry(pos->member.next, typeof(*pos), member))

//如果遍历链表不是从头开始,而是从某个已知的节点pos开始, 从当前的位置往后遍历,注意和头的情况区分
#define dlist_for_each_entry_continue(pos, head, member) 		\
    for (pos = dlist_entry(pos->member.next, typeof(*pos), member);	\
         &pos->member != (head);	\
         pos = dlist_entry(pos->member.next, typeof(*pos), member))


//双向链表的反向遍历,从后往前
#define dlist_for_each_prev(pos, head) \
    for (pos = (head)->prev; pos != (head); pos = pos->prev)

//双向链表遍历的时候可以同时删除pos节点
#define dlist_for_each_safe(pos, n, head) \
    for (pos = (head)->next, n = pos->next; pos != (head); \
        pos = n, n = pos->next)


//提供一个和pos一样的指针n,在for循环中暂时保留pos的下一个节点的地址,避免因pos节点被释放而造成断链的结果
#define dlist_for_each_entry_safe(pos, n, head, member)			\
    for (pos = list_entry((head)->next, typeof(*pos), member),	\
        n = list_entry(pos->member.next, typeof(*pos), member);	\
         &pos->member != (head); 					\
         pos = n, n = dlist_entry(n->member.next, typeof(*n), member))






#endif

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值