天天看点

通用的双向链表(值得收藏)

头文件

typedef struct tagListNode

{

 struct tagListNode *pNext;

 struct tagListNode *pPrev;

}ListNode;

//遍历所有节点

#define List_ForEach(pos,head) /

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

//遍历所有节点(允许删除当前节点pos)

#define List_ForEachSafe(pos,next,head) /

 for ((pos) = (head)->pNext,(next)=(pos)->pNext; (pos) != (head); (pos) = (next),(next)=(next)->pNext)

#define List_Entry(p,type,member) (type*)((char *)(p)-(int)(&(((type*)0)->member)))

//检查链表是否为空

#define List_Empty(head) ((head)->pNext==(head))

//声明一个初始化的链表头

#define LIST_HEAD(name) ListNode name = {&name,&name}

//初始化链表头

#define INIT_LIST_HEAD(pNode) (pNode)->pPrev=(pNode)->pNext=(pNode);

//把一个新节点插入到pNode之前

extern void List_InsertBefore(ListNode *pNew, ListNode *pNode);

//把一个新节点插入到pNode之后

extern void List_InsertAfter(ListNode *pNew, ListNode *pNode);

//从链表删除一个节点

extern void List_Del(ListNode *entry); 

源文件

#define List_Add(newl,prev,next);  /

    do{         /

    newl->pNext = next;     /

    newl->pPrev = prev;     /

    (newl->pNext)->pPrev = newl;  /

    (newl->pPrev)->pNext = newl;  /

}while(0);

//把一个新节点插入到pNode之前

void List_InsertBefore(ListNode *newl, ListNode *pNode)

{

 List_Add(newl,pNode->pPrev,pNode);

}

//把一个新节点插入到pNode之后

void List_InsertAfter(ListNode *newl, ListNode *pNode)

{

 List_Add(newl,pNode,pNode->pNext);

}

//从链表删除一个节点

void List_Del(ListNode *entry)

{

 entry->pPrev->pNext=entry->pNext;

 entry->pNext->pPrev=entry->pPrev;

 entry->pPrev=0;

 entry->pNext=0;

}