• 双链表操作


    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))  
      
  • 相关阅读:
    [Flink] 从 RabbitMQ 读取并计算后输出到 MySQL
    极光笔记丨搭建UMS私有云文件服务器
    极光笔记丨Spark SQL 在极光的建设实践
    Iog4j2漏洞相关技术分析
    极光笔记丨关于数据大屏一比一还原设计稿这件事
    极光笔记|基于CMPP协议集成短信测试桩全流程实践分享
    极光笔记|数据服务平台一期建设
    【记录】GIT常用命令
    【原创】使用micrel的千兆PHY芯片ksz9021GN和KSZ9021GQ前要注意
    【记录】调试千兆以太网PHY芯片DP83865的痛苦经历
  • 原文地址:https://www.cnblogs.com/wangzhijun/p/3179188.html
Copyright © 2020-2023  润新知