dlist.h:
#ifndef DLIST_H #define DLIST_H typedef int Item; struct dnode { Item item; struct dnode *prev; struct dnode *next; }; typedef struct dnode* dlist; void DListAddItem(dlist *plist, Item item); struct dnode* DListSearchItem(dlist *plist, Item item); void DListDelItem(dlist *plist, Item item); #endif
dlist.cpp:
#include "stdafx.h" #include "dlist.h" #include <assert.h> #include <stdlib.h> static inline void CopyItem (Item item, struct dnode *pnode) { pnode->item = item; } static inline int ItempCmp(Item item1, Item item2) { return item1 > item2 ? 1 : (item1 == item2 ? 0 : -1); } /********************************************** 添加元素到链表尾部 **********************************************/ void DListAddItem(dlist *plist, Item item) { assert(NULL != plist); struct dnode* pnew = (struct dnode *)malloc(sizeof(struct dnode)); assert(NULL != plist); CopyItem(item, pnew); pnew->next = NULL; pnew->prev = NULL; struct dnode* pscan = *plist; if (NULL == pscan) // 空链表 { pnew->next = pnew; pnew->prev = pnew; *plist = pnew; } else { pnew->prev = pscan->prev; pnew->next = pscan; pscan->prev->next = pnew; pscan->prev = pnew; } } /********************************************** 搜索元素 链表中存在元素,则返回第一个匹配元素的节点 若不存在或者链表为空,则返回空指针 **********************************************/ struct dnode* DListSearchItem(dlist *plist,Item item) { assert(NULL != plist); struct dnode *pscan = *plist; if (NULL == pscan) return (struct dnode*)0; do { if (0 == ItempCmp(item, pscan->item)) return pscan; pscan = pscan->next; }while(pscan != *plist); return (struct dnode*)0; } /********************************************** 删除元素 **********************************************/ void DListDelItem(dlist *plist, Item item) { struct dnode *pdel; pdel = DListSearchItem(plist, item); if (NULL != pdel) { pdel->prev->next = pdel->next; pdel->next->prev = pdel->prev; if (*plist == pdel) // 删除头结点 { *plist = pdel->next; if (*plist == pdel) // 链表只有1个节点 { *plist = NULL; } } free(pdel); } } /************************************************************************* linux中的双链表实现: 此实现方案最大的好处是不需要Item每变换一次就重新定义一次节点 **************************************************************************/ // 双链表---begin /********************************************************** TYPE: 结构体类型名 MEMBER: 结构体成员名 **********************************************************/ #define offsetof(TYPE, MEMBER) (((TYPE *)0)->MEMBER) /********************************************************** ptr: 结构体成员指针 type: 结构体类型名 member: ptr对应的结构体成员名 **********************************************************/ #define container_of(ptr, type, member) (type*)((char *)ptr - offsetof(type, member)) struct list { struct list *prev, *next; }; #define LIST_HEAD_INIT(name) {&(name), &(name)} #define LIST_HEAD(name) struct list name = LIST_HEAD_INIT(name) static inline void list_init(struct list *list) { list->next = list; list->prev = list; } static inline int list_empty(struct list *list) { return list->next == list; } // 将new_link插入到link之前 static inline void list_insert(struct list *link, struct list *new_link) { new_link->prev = link->prev; new_link->next = link; new_link->prev->next = new_link; new_link->next->prev = new_link; } static inline void list_append(struct list *list, struct list *new_link) { list_insert(list, new_link); } static inline void list_remove(struct list *link) { link->prev->next = link->next; link->next->prev = link->prev; } /********************************************************** 获取link节点对应的结构体变量地址 link: 链表节点指针 type: 结构体类型名 member: 结构体成员变量名 **********************************************************/ #define list_entry(link, type, member) ((type *)((char *)(link)-(unsigned long)(&((type *)0)->member))) /********************************************************** 获取链表头节点对应的结构体变量地址 list: 链表头指针 type: 结构体类型名 member: 结构体成员变量名 Note: 链表头节点实际为链表头的下一个节点,链表头未使用,相当于哨兵 **********************************************************/ #define list_head(list, type, member) list_entry((list)->next, type, member) /********************************************************** 获取链表尾节点对应的结构体变量地址 list: 链表头指针 type: 结构体类型名 member: 结构体成员变量名 **********************************************************/ #define list_tail(list, type, member) list_entry((list)->prev, type, member) /********************************************************** 返回链表下一个节点对应的结构体指针 elm: 结构体变量指针 type: 结构体类型名 member: 结构体成员变量名(链表变量名) **********************************************************/ #define list_next(elm,type,member) list_entry((elm)->member.next, type, member) /********************************************************** 遍历链表所有节点对应的结构体 pos: 结构体指针 type: 结构体类型名 list: 链表头指针 member: 结构体成员变量名(链表变量名) Note: 链表头未使用,因此遍历结束后,pos指向的不是有效的结构体地址 **********************************************************/ #define list_for_each_entry(pos, type, list, member) for (pos = list_head(list, type, member); &pos->member != (list); pos = list_next(pos, type, member))