單向列表的實現代碼,以及註釋解釋筆記

 1 *define a structure for linked lists*/
 2 /*這裏定義了一個list鏈表的類型*/
 3 
 4 typedef struct List_  5 {  6     int size;  7     int (*match)(const void *key1,const void *key2);  8     void (*destroy)(void *data);  9     ListElmt *head;                      //head指向鏈表頭結點的指針
10     ListElmt *tail;                      //tail是指向鏈表中末尾的元素的指針
11 }List; 12 
13 
14 
15 /*public interface*/
16 
17 void list_init(List *list,void(*destroy)(void *data));      //鏈表初始化的,或者說建立的函數定義;
18 void list_destroy(List *list);                             // 鏈表數據結構的析構函數的定義;
19 int list_ins_next(List *list,ListElmt *element,const void *data);       //在list指定的的鏈表的element元素後面插入一個元素值data,if true return0;else return -1;
20 int list_rem_next(List *list,ListElmt *element,const void **data);   //在list指定的鏈表元素element元素後面移除一個元素值data,返回值同上;
21 
22 /*下面是預先定義的宏*/
23 #define list_size(list) ((list)->size)     //鏈表中元素的個數
24 #define list_head(list) ((list)->head)    //鏈表中的頭元素的指針
25 #define list_tail(list) ((list)->tail);   //鏈表中末尾元素的指針
26 #define list_is_head(list,element) ((element) == (list)->head ?1:0)    //判斷元素是否是頭元素
27 #define list_is_tail(element) ((element)->next==NULL ?1:0)            //判斷元素是否是最後一個元素
28 #define list_data(element) ((element)->data)                   //結點的數據
29 #define list_next(element) ((element)->next)                   //下一個元素的指針
30 
31 
32 #endif

上面是單項列表的實現的頭文件,定義了各類接口,以及元素結點,鏈表結構。數據結構

下面是單項列表實現的過程。函數

 1 include "list.h"
 2 
 3 #include<stdlib.h>
 4 #include<stdio.h>
 5 #include<string.h>
 6 
 7 
 8 //list_init
 9 void list_init(List *list,void (*destroy)(void *data)){  10          //初始化這個列表
 11          list->size=0;  12          list->destroy =destroy;  13          list->head=NULL;  14          list->tail=NULL;  15 
 16 
 17          return;  18 }  19 
 20 
 21 
 22 //list_destroy
 23 
 24 void list_destroy(List *list){  25           void *data;  26                                          //下面移除掉鏈表裏的每個元素
 27           while(list_size(list)>0){  28                  if(list_rem_next(list,NULL,(const void **)&data)==0 && list->destroy!=NULL){  29                                    list->destroy(data);       //引用一個用戶定義的函數去釋放申請的內存空間
 30  }  31  }  32 memset(list,0,sizeof(data));//沒有運算被容許,可是要清空結構做爲預處理
 33 return;  34 }  35 
 36 
 37 //list_ins_next
 38 
 39 int list_ins_next(List *list,ListElmt *element,const void *data){  40               ListElmt *new_element;  41               if((new_element=(ListElmt *)malloc(sizeof(ListElmt)))==NULL){  42                 return -1;             /*若是內存申請失敗,則返回-1,這裏把新結點的內存申請放在判斷條件裏進行了*/
 43  }  44               new_element->data=(void*)data;   //把要插入的元素值賦給新的位置
 45               if(element==NULL){               //要插入位置的元素不爲空的話
 46                 if(list_size(list)==0){          //若是鏈表的大小爲0,那麼把要插入的元素,直接給到鏈表的末尾,最後一個
 47                   list->tail==new_element;  48 
 49                   new_element->next=list->head;    //把這個元素結點的下一個地址賦值給鏈表頭元素
 50                   list->head=new_element;          //鏈表的頭元素,就是這個新插入的元素成員
 51  }  52  }  53               else{                                    //若是這個要插入的位置的元素不爲空
 54                 if(element->next==NULL){                //判斷這個插入位置是否是最後一個,
 55                   list->tail=new_element;               //若是是最後一個的話,把要插入的結點放在最後
 56                   new_element->next=element ->next;     //新插入的結點的指向本位置下一個元素的指針
 57                   element->next=new_element->next;     //插入位置的元素的指針指向新插入的元素
 58  }  59  }  60 
 61               list->size++;       //插入成功之後,給鏈表的大小加上一
 62     return 0;  63 }  64 
 65 
 66 
 67 //list_rem_next
 68 int list_rem_next(List *list,ListElmt *element,const void **data){  69          ListElmt *old_element;  70 
 71          if(list_size(list)==0){  72               return -1;                        /*若是給定的列表爲空表的話,直接返回-1*/
 73  }  74          if(element==NULL)                      //若是要刪除的位置爲NULL的話,執行
 75  {  76                *data=list->head->data;             //數據等於鏈表頭的元素值
 77                old_element =list->head;             //把鏈表頭元素地址給old_element
 78                list->head=list->head->next;         //鏈表頭結點移動到下一個元素結點
 79 
 80                if(list_size(list)==1){  81                  list->tail=NULL;                      //若是隻有一元素的話,末尾的結點指向空指針
 82  }  83  }  84          else
 85            {                                              //若是刪除的位置不爲空
 86             if(element->next==NULL){  87               return -1;  88  }  89             *data=element->next->data;  90             old_element=element->next;  91             element->next=element->next->next;  92             if(element->next==NULL)  93             list->tail=element;  94  }  95     free(old_element);                                //刪除結束後把不須要的結點從內存釋放掉
 96     list->size--;       //鏈表的大小減一
 97     return 0;  98 }  99 
100 
101 
102 int main(void){ 103        printf("end"); 104        return 0; 105 }

最後面的main函數是爲了,編譯成功執行一會兒。spa

若是是使用鏈表的話,儘可能把實現的代碼,放在單獨的c文件裏。指針

相關文章
相關標籤/搜索