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文件裏。指針