zoukankan      html  css  js  c++  java
  • 通用链表实现(参考Linux List)

      最近参考Linux实现的通用双向链表时,因typeof并不是标准c规定的关键字,除GCC编译器外其他编译器未必支持typeof关键字,所以在使用上并不能想Linux所实现的链表哪样灵活,它要求将连接器即链表结构作为用户自定义结构体的第一个元素使用,话不多说,直接上代码,内嵌详细注释。

    IList.h

      1 #ifndef _I_LIST_H_2012_11_23_
      2 #define _I_LIST_H_2012_11_23_
      3 
      4 #ifdef __cplusplus
      5 extern "C" {
      6 #endif
      7 
      8 /** rief 双向链表连接器
      9  *  details 实现用户自定义结构链表的连接器的结构定义,使用注意事项:
     10     1. 务必将其嵌入到用户自定义结构体元素的顶端;
     11     2. 务必使用结构类型而非其指针类型嵌入到用户自定义结构体
     12  *  	ypedef typedef struct _IList IList,*pIList
     13  */
     14 typedef struct _IList
     15 {
     16     struct _IList *_prev;
     17     struct _IList *_next;
     18 }IList, *pIList;
     19 
     20 /**
     21   rief    遍历链表所有节点
     22   details  遍历链表所有节点,在遍历过程中,请勿执行添加、删除操作
     23 
     24   param[in]  pList 链表对象
     25   param[out] pLink 节点
     26  */
     27 #define IList_Foreach(pList, pos) 
     28     for ( 
     29         pos = pos = (pList)->_next; 
     30         pos != (pList); 
     31         pos = pos->_next 
     32     )
     33 
     34 /**
     35   rief    遍历链表所有节点
     36   details  安全遍历链表所有节点,在遍历过程中,可以删除节点
     37 
     38   param[in]  pList 链表对象
     39   param[out] pLink 节点
     40  */
     41 #define IList_Foreach_Salf(pList, temp, pos) 
     42     for ( 
     43         pos = (pList)->_next, temp = pos->_next; 
     44         pos != (pList); 
     45         pos = temp, temp = pos->_next
     46     )
     47 
     48 /**
     49   rief    链表初始化
     50 
     51   param[in]  pList 链表对象
     52  */
     53 void IList_Init(pIList pList);
     54 
     55 /**
     56   rief    插入新节点
     57   details  将新节点插入链表指定节点之前
     58 
     59   param[in]  pList 链表对象
     60   param[in]  pLink 指定节点
     61   param[in]  pNewLink 带插入节点
     62  */
     63 void IList_Insert(pIList pLink, pIList pNewLink);
     64 
     65 /**
     66   rief    插入新节点至链表尾部
     67 
     68   param[in]  pList 链表对象
     69   param[in]  pLink 指定节点
     70   param[in]  pNewLink 带插入节点
     71  */
     72 void IList_Append(pIList pList, pIList pNewLink);
     73 
     74 /**
     75   rief    插入新节点至链表尾头部
     76 
     77   param[in]  pList 链表对象
     78   param[in]  pLink 指定节点
     79   param[in]  pNewLink 带插入节点
     80  */
     81 void IList_Prepend(pIList pList, pIList pNewLink);
     82 
     83 /**
     84   rief    删除指定节点
     85 
     86   param[in]  pList 链表对象
     87   param[in]  pLink 带删除的节点
     88  */
     89 void IList_Remove(pIList pLink);
     90 
     91 /**
     92   rief    获取表头节点
     93 
     94   param[in]  pList 链表对象
     95 
     96   
    eturn   NULL: 链表为空
     97             其他: 表头节点地址
     98  */
     99 pIList IList_Head(pIList pList);
    100 
    101 /**
    102   rief    获取表尾节点
    103 
    104   param[in]  pList 链表对象
    105 
    106   
    eturn   NULL: 链表为空
    107             其他: 表尾节点地址
    108  */
    109 pIList IList_Tail(pIList pList);
    110 
    111 /**
    112   rief    检测链表是否为空
    113 
    114   param[in]  pList 链表对象
    115 
    116   
    eturn   0: 链表非空
    117             1: 链表为空
    118  */
    119 int IList_IsEmpty(pIList pList);
    120 /**
    121   rief    获取链表节点数
    122 
    123   param[in]  pList 链表对象
    124 
    125   
    eturn   链表节点数
    126  */
    127 int IList_Size(pIList pList);
    128 
    129 /**
    130   rief    获取指定节点的后一节点
    131 
    132   param[in]  pList 链表对象
    133   param[in]  pLink 指定的节点
    134 
    135   
    eturn   NULL: 指定节点为尾节点
    136             其他: 指定节点后一节点地址
    137  */
    138 pIList IList_Next(pIList pList, pIList pLink);
    139 
    140 /**
    141   rief    获取指定节点的前一节点
    142 
    143   param[in]  pList 链表对象
    144   param[in]  pLink 指定的节点
    145 
    146   
    eturn   NULL: 指定节点为头节点
    147             其他: 指定节点前一节点地址
    148  */
    149 pIList IList_Prev(pIList pList, pIList pLink);
    150 
    151 /**
    152   rief    获取链表中第index个节点
    153 
    154   param[in]  pList 链表对象
    155   param[in]  index 节点序号,从1计数
    156 
    157   
    eturn   NULL: 指定序号无节点
    158             其他: 链表中第index所对应的节点
    159  */
    160 pIList IList_Nth(pIList pList, int index);
    161 
    162 /**
    163   rief    获取链表中指定节点的序号
    164 
    165   param[in]  pList 链表对象
    166   param[in]  pLink 指定节点
    167 
    168   
    eturn   NULL: 指定序号无节点
    169             其他: 链表中第index所对应的节点
    170  */
    171 int IList_Find(pIList pList, pIList pLink);
    172 
    173 #ifdef __cplusplus
    174 }
    175 #endif
    176 
    177 #endif//_I_LIST_H_2012_11_23_

    IList.c

      1 #include <stdio.h>
      2 #include "iList.h"
      3 
      4 void IList_Init(pIList pList)
      5 {
      6     pList->_prev = pList;
      7     pList->_next = pList;
      8 }
      9 
     10 void IList_Insert(pIList pLink, pIList pNewLink)
     11 {
     12     pNewLink->_prev = pLink->_prev;
     13     pNewLink->_next = pLink;
     14     pNewLink->_prev->_next = pNewLink;
     15     pNewLink->_next->_prev = pNewLink;
     16 }
     17 
     18 void IList_Append(pIList pList, pIList pNewLink)
     19 {
     20     IList_Insert(pList, pNewLink);
     21 }
     22 
     23 void IList_Prepend(pIList pList, pIList pNewLink)
     24 {
     25     IList_Insert(pList->_next, pNewLink);
     26 }
     27 
     28 void IList_Remove(pIList pLink)
     29 {
     30     pLink->_prev->_next = pLink->_next;
     31     pLink->_next->_prev = pLink->_prev;
     32 }
     33 
     34 pIList IList_Head(pIList pList)
     35 {
     36     return pList->_next != pList ? pList->_next : NULL;
     37 }
     38 
     39 pIList IList_Tail(pIList pList)
     40 {
     41     return pList->_prev != pList ? pList->_prev : NULL;
     42 }
     43 
     44 int IList_IsEmpty(pIList pList)
     45 {
     46     return pList->_next == pList;
     47 }
     48 
     49 int IList_Size(pIList pList)
     50 {
     51     int count = 0;
     52     pIList temp = NULL;
     53 
     54     if (pList->_next == pList)
     55         return 0;
     56 
     57     IList_Foreach(pList, temp)
     58     {
     59         count ++;
     60     }
     61 
     62     return count;
     63 }
     64 
     65 pIList IList_Next(pIList pList, pIList pLink)
     66 {
     67     return pLink->_next != pList ? pLink->_next : NULL;
     68 }
     69 
     70 pIList IList_Prev(pIList pList, pIList pLink)
     71 {
     72     return pLink->_prev != pList ? pLink->_prev : NULL;
     73 }
     74 
     75 pIList IList_Nth(pIList pList, int index)
     76 {
     77     pIList pLink = NULL;
     78     int count = 0;
     79 
     80     IList_Foreach(pList, pLink)
     81     {
     82         count ++;
     83         if (count == index)
     84             return pLink;
     85     }
     86 
     87     return NULL;
     88 }
     89 
     90 int IList_Find(pIList pList, pIList pLink)
     91 {
     92     pIList pTemp = NULL;
     93     int index = 1;
     94 
     95     pTemp = IList_Head(pList);
     96 
     97     while ((pTemp != NULL) && (pTemp != pLink))
     98     {
     99         index++;
    100         pTemp = IList_Next(pList, pTemp);
    101     }
    102 
    103     if (pTemp == NULL)
    104         return (-1);
    105     else
    106         return (index);
    107 }

     IListTest.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "iList.h"
    
    typedef struct _Student
    {
        IList _list;
    
        int _id;
        char *name;
    }Student, *pStudent;
    
    int main(int argc, char *argv[])
    {
        int i = 0;
        int num = 10;
        int count = 0;
        pStudent temp= NULL;
        pIList list, link;
    
        if (argc > 1)
            num = atoi(argv[1]);
    
        list = (IList *)malloc(sizeof(IList));
        if (!list)
        {
            printf("Error in malloc.
    ");
            return -1;
        }
        memset(list, 0, sizeof(IList));
    
        IList_Init(list);
        for (i = 0; i < num; i ++)
        {
            temp = malloc(sizeof(Student));
            if (!temp)
                return -1;
            memset(temp, 0, sizeof(Student));
            temp->_id = i + 1;
            IList_Append(list, &temp->_list);
            //IList_Prepend(list, &temp->_list);
        }
    
        IList_Foreach(list, link)
        {
            temp = (pStudent)link;
            printf("%d	", temp->_id);
        }
        printf("
    ");
    
        printf("Input the num(1 ~ %d) that you want to:
    ", IList_Size(list));
        scanf("%d", &count);
        link = IList_Nth(list, count);
        printf("Num %d id: %d
    ", count, ((pStudent)link)->_id);
        printf("Id %d num: %d
    ", ((pStudent)link)->_id, IList_Find(list, link));
    
        printf("List count: %d
    ", IList_Size(list));
        /*for (link = IList_Head(list);!IList_IsEmpty(list);)
        {
            pIList tLink = link;
            link = IList_Next(list, link);
            IList_Remove(tLink);
            free(tLink);
        }*/
        do 
        {
            pIList n, pos;
            IList_Foreach_Salf(list, n, pos)
            {
                IList_Remove(pos);
                free(pos);
            }
        } while (0);
        printf("List count: %d
    ", IList_Size(list));
    
        free(list);
    
        return 0;
    }
  • 相关阅读:
    c++vector(入门级)
    端口扫描(TCP)
    推荐安全程序员的书单(系统、网络、安全等)
    My latest news(--2016.12.31)
    HTML+JS+DOM【选项卡自动切换】
    20170916考试总结
    [Usaco2014 Mar]Sabotage
    [SHOI2014]概率充电器
    [Usaco2010 Dec]Exercise 奶牛健美操
    [JZOJ4687]奇袭
  • 原文地址:https://www.cnblogs.com/hackvilin/p/3255013.html
Copyright © 2011-2022 走看看