双链表操作

来源:互联网 发布:淘宝交不了保证金 编辑:程序博客网 时间:2024/06/09 16:38

dlist.h:

#ifndef DLIST_H#define DLIST_Htypedef 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))    

 

0 0
原创粉丝点击