linux内核链表c实现,双向循环链表---仿照linux内核实现

myList.h#ifndef MYLIST_H_INCLUDED

#define MYLIST_H_INCLUDED

/*

仿照linux的链表操作的实现

*/

#undef NULL

#ifdef __cplusplus

#define NULL 0

#else

#define NULL ((void *)0)

#endif

struct list_head

{

struct list_head *next;

struct list_head *prev;

};

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

#define LIST_HEAD(name) \

struct list_head name = LIST_HEAD_INIT(name)

//在(TYPE*)结构体中找到(MEMBER)成员的位置

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

//找到type的开始位置

#define list_entry(ptr, type, member) \

(type *)((char *)ptr - offsetof(type,member))

//向后遍历链表。pos为当前位置,head为开始位置

#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)

//向前遍历链表。pos为当前位置,head为开始位置

#define list_for_each_prev(pos, head) \

for (pos = (head)->prev; pos != (head); pos = pos->prev)

#define list_for_each_prev_safe(pos, n, head) \

for (pos = (head)->prev, n = pos->prev; pos != (head); pos = n, n = pos->prev)

//???

#define list_first_entry(ptr, type, member) \

list_entry((ptr)->next, type, member)

//初始化链表(链表头)

static inline void INIT_LIST_HEAD(struct list_head *list)

{

list->next = list;

list->prev = list;

}

//添加一个节点到链表中的基本操作

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;

}

//在链表头之后增加一个新节点。如1->2->3,增加4之后为1->4->2->3

static inline void list_add(struct list_head *new, struct list_head *head)

{

__list_add(new, head, head->next);

}

//在链表的尾部增加一个新节点,如1->2->3,增加4之后为1->2->3->4

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;

}

//删除一个链表中的节点,*entry为从链表找中摘除的节点,如果有内存申请则需要手动释放

static inline void list_del(struct list_head *entry)

{

__list_del(entry->prev, entry->next);

entry->next = NULL;

entry->prev = NULL;

}

//删除一个链表中的节点并把删除的节点初始化,*entry为从链表找中摘除的节点,如果有内存申请则需要手动释放

static inline void list_del_init(struct list_head *entry)

{

__list_del(entry->prev, entry->next);

INIT_LIST_HEAD(entry);

}

//使用new替换链表中的old

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;

}

//使用new替换链表中的old并且把old初始化,如果old是链表头则相当于清空链表

static inline void list_replace_init(struct list_head *old, struct list_head *new)

{

list_replace(old, new);

INIT_LIST_HEAD(old);

}

//将list从链表中取出,然后移动到head的之后的位置。如果head是链表头则是移动到链表的第一个位置

static inline void list_move(struct list_head *list, struct list_head *head)

{

__list_del(list->prev, list->next);

list_add(list, head);

}

//将list从链表中取出,然后移动到head的最后一个位置。如果head是链表头则是移动到链表的尾部

static inline void list_move_tail(struct list_head *list, struct list_head *head)

{

__list_del(list->prev, list->next);

list_add_tail(list, head);

}

//判断链表是否为空

static inline int list_empty(const struct list_head *head)

{

return head->next == head;

}

//判断链表是否为空。条件更加充足

static inline int list_empty_careful(const struct list_head *head)

{

struct list_head *next = head->next;

return (next == head) && (next == head->prev);

}

/*******************************不常用的操作*********************************/

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

static inline int list_is_last(const struct list_head *list, const struct list_head *head)

{

return list->next == head;

}

//判断链表中是否只有一个节点

static inline int list_is_singular(const struct list_head *head)

{

return !list_empty(head) && (head->next == head->prev);

}

//将一个链表拆分为两条链表的基本操作

static inline void __list_cut_position(struct list_head *list, struct list_head *head, struct list_head *entry)

{

struct list_head *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;

}

/*

将一个链表拆分成两条

*list为拆分后的新链表的头,*head为被拆分链表的头,*entry为拆分位置

拆分后list->next = entry, head->next = entry->next

既是entry后面的节点被加到list的后面,原链表保留entry之前的节点

head->1->2->3->10->20->30,entry->10.拆分后:head->10->20->30, list->1->2->3

*/

static inline void list_cut_position(struct list_head *list, struct list_head *head, struct list_head *entry)

{

if (list_empty(head))

return;

if (list_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 list_head *list, struct list_head *prev, struct list_head *next)

{

struct list_head *first = list->next;

struct list_head *last = list->prev;

first->prev = prev;

prev->next = first;

last->next = next;

next->prev = last;

}

/*

合并两条链表

将list链表加入到head的后面

list->1->2->3,head->10->20->30。合并后:head->1->2->3->10->20->30

*/

static inline void list_splice(const struct list_head *list, struct list_head *head)

{

if (!list_empty(list))

__list_splice(list, head, head->next);

}

/*

合并两条链表

将list链表加入到head的后面,list为必须为链表头,合并后将其初始化

list->1->2->3,head->10->20->30。合并后:head->1->2->3->10->20->30

*/

static inline void list_splice_init(struct list_head *list, struct list_head *head)

{

if (!list_empty(list))

{

__list_splice(list, head, head->next);

INIT_LIST_HEAD(list);

}

}

/*

合并两条链表

将list链表加入到head的链表尾部

list->1->2->3,head->10->20->30。合并后:head->10->20->30->1->2->3

*/

static inline void list_splice_tail(struct list_head *list, struct list_head *head)

{

if (!list_empty(list))

__list_splice(list, head->prev, head);

}

/*

合并两条链表

将list链表加入到head的链表尾部。list必须是头节点,合并后初始化list

list->1->2->3,head->10->20->30。合并后:head->10->20->30->1->2->3

*/

static inline void list_splice_tail_init(struct list_head *list, struct list_head *head)

{

if (!list_empty(list))

{

__list_splice(list, head->prev, head);

INIT_LIST_HEAD(list);

}

}

#endif // MYLIST_H_INCLUDED

main.c#include 

#include 

#include "myList.h"

#include "memory.h"

#define RETURN_OK 0

#define RETURN_ERROR -1

//结构体的定义需要放在头文件中,此处做了简便处理

typedef struct tag_myList

{

int data;

struct list_head stListNode;  //该指针一般放在结构体定义的开头

}myList;

struct list_head g_stListHead;    //全局变量,作为链表的头

//申请一个节点

myList* newNode()

{

myList *pstTemp = NULL;

//为节点申请内存

pstTemp = (myList*)malloc(sizeof(myList));

if (NULL == pstTemp)

{

return NULL;

}

INIT_LIST_HEAD(&(pstTemp->stListNode));

pstTemp->data = 0;

return pstTemp;

}

int main()

{

int i;

struct list_head stTempHead;    //作为拆分或者合并的链表的头节点

struct list_head *pstEntry = NULL;

myList* pstTemp = NULL;

struct list_head *pos = NULL;

struct list_head *n = NULL;

//初始化

INIT_LIST_HEAD(&g_stListHead);

INIT_LIST_HEAD(&stTempHead);

for (i = 0; i 

{

pstTemp = newNode();

if (NULL == pstTemp)

{

exit(0);    //内存申请失败则退出,简单的处理

}

pstTemp->data = i;

//将节点加入链表头部

list_add(&pstTemp->stListNode, &g_stListHead);

}

for (i = 5; i 

{

pstTemp = newNode();

if (NULL == pstTemp)

{

exit(0);    //内存申请失败则退出,简单的处理

}

pstTemp->data = i;

//将节点加入链表尾部

list_add_tail(&pstTemp->stListNode, &g_stListHead);

}

//遍历链表

list_for_each(pos, &g_stListHead)

{

//通过偏移找到结构体开始的位置,list_entry已经将偏移后的指针强制转换为该结构体

pstTemp = list_entry(pos, myList, stListNode);

printf("%d\t", pstTemp->data);

if (0 == pstTemp->data)

{

pstEntry = &pstTemp->stListNode;     //将0所在的位置作为拆分或者合并的节点位置

}

}

printf("\n");

list_cut_position(&stTempHead, &g_stListHead, pstEntry);

printf("cut node after g_stListHead:");

list_for_each(pos, &g_stListHead)

{

//通过偏移找到结构体开始的位置,list_entry已经将偏移后的指针强制转换为该结构体

pstTemp = list_entry(pos, myList, stListNode);

printf("%d\t", pstTemp->data);

}

printf("\n");

printf("cut node after stTempHead:");

list_for_each(pos, &stTempHead)

{

//通过偏移找到结构体开始的位置,list_entry已经将偏移后的指针强制转换为该结构体

pstTemp = list_entry(pos, myList, stListNode);

printf("%d\t", pstTemp->data);

}

printf("\n");

list_splice_init(&g_stListHead, &stTempHead);   //list_splice在遍历的时候就会有问题

printf("splice node after stTempHead:\t");

list_for_each(pos, &stTempHead)

{

//通过偏移找到结构体开始的位置,list_entry已经将偏移后的指针强制转换为该结构体

pstTemp = list_entry(pos, myList, stListNode);

printf("%d\t", pstTemp->data);

}

printf("\n");

printf("splice node after g_stListHead:\t");

list_for_each(pos, &g_stListHead)

{

//通过偏移找到结构体开始的位置,list_entry已经将偏移后的指针强制转换为该结构体

pstTemp = list_entry(pos, myList, stListNode);

printf("%d\t", pstTemp->data);

}

return 0;

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值