侵入式链表

普通链表:

我们经常使用的普通链表是每个节点的next指针指向下一个节点的首地址:
普通链表

具体代码实现如下:

struct link
{    
    int data;
    struct link* next;
}

普通链表的缺点:

  • 一条链表上的所有节点的数据类型需要完全一致
  • 对某条链表的操作如插入,删除等只能对这种类型的链表进行操作,如果链表的类型换了,就要重新再封装出一套一样的操作,泛化能力差;

侵入式链表:

侵入式链表的节点的链接成员指向的是下一个节点的链接成员:

侵入式链表

节点结构如下:

typedef struct list_structure
{
    struct list_structure* next;
}ListObj;

typedef struct
{
	int data;
	ListObj list;
} Node;

侵入式链表的优点:

  • 节点类型无需一致,只需要包含ListObj成员即可
  • 泛化能力强,所有链表的操作方式均可统一;

如何访问侵入式链表中的节点元素?首先要掌握两个内容:

学会这两个内容就能明白是如何对节点进行操作的了。


完整代码:

头文件:

#ifndef _LIST_H
#define _LIST_H

#define offset_of(type, member)             (unsigned long) &((type*)0)->member

#define container_of(ptr, type, member) ({          \
     const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
     (type *)( (char *)__mptr - offset_of(type,member) );})


typedef struct list_structure
{
    struct list_structure* next;
    struct list_structure* prev;
}ListObj;


#define LIST_HEAD_INIT(name)    {&(name), &(name)}
#define LIST_HEAD(name)         ListObj name = LIST_HEAD_INIT(name)


#define list_entry(node, type, member) \
    container_of(node, type, member)


#define list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)


#define list_for_each_safe(pos, n, head) \
  for (pos = (head)->next, n = pos->next; pos != (head); \
    pos = n, n = pos->next)


void list_init(ListObj* list);
void list_insert_after(ListObj* list, ListObj* node);
void list_insert_before(ListObj* list, ListObj* node);
void list_remove(ListObj* node);
int list_isempty(const ListObj* list);
unsigned int list_len(const ListObj* list);

#endif

源文件:

 #include "link_list.h"
 
void list_init(ListObj* list)
{
    list->next = list->prev = list;
}

void list_insert_after(ListObj* list, ListObj* node)
{
    list->next->prev = node;
    node->next = list->next;

    list->next = node;
    node->prev = list;
}

void list_insert_before(ListObj* list, ListObj* node) 
{
    list->prev->next = node;
    node->prev = list->prev;
    list->prev = node;
    node->next = list;
}

void list_remove(ListObj* node)
{
    node->next->prev = node->prev;
    node->prev->next = node->next;

    node->next = node->prev = node;
}

int list_isempty(const ListObj* list)
{
    return list->next == list;
}

unsigned int list_len(const ListObj* list)
{
    unsigned int len = 0;
    const ListObj* p = list;
    while (p->next != list)
    {
        p = p->next;
        len++;
    }
    return len;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值