双链表操作

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

 

posted @ 2013-07-09 09:17  尘虑萦心  阅读(230)  评论(0编辑  收藏  举报