雙向鏈表的實現與分析
雙向鏈表的組成 :1、數據成員;2、指向下一個元素的next指針;3、指向前一個元素的prev指針。
數據結構DListElmt:代表雙向鏈表中的單個元素(節點)。
數據結構DList:代表雙向鏈表數據結構,該結構的成員同前面介紹的單鏈表相似。
示例1:雙向鏈表抽象數據類型的頭文件
/*dlist.h*/ #ifndef DLIST_H #define DLIST_H /*定義雙向鏈表中的元素*/ typedef struct DListLemt_ { void *data; struct DListElmt_ *prev; struct DlistElmt_ *next; }DListElmt; /*定義雙向鏈表*/ typedef struct DList_ { int size; int (*match)(const void *key1,const void *key2); void (*destroy)(void *data); DListElmt *head; DlistElmt *tail; }DList; /*公共接口*/ void dlist_init(DList *list,void (*destroy)(void *data)) ; void dlist_destroy(DList *list); int dlist_ins_next(DList *list,DListElmt *element,const void *data); int dlist_ins_prev(Dlist *list,DListElmt *element,const void *data); int dlist_remove(DList *list,DlistElmt *element,void **data); #define dlist_size(list)((list)->size) #define dlist_head(list)((list)->head) #define dlist_tail(list)((list)->tail) #define dlist_is_head(element)((element)->prev == NULL ? 1 : 0) #define dlist_is_tail(element)((element)->next == NULL ? 1 : 0) #define dlist_data(element)((element)->data) #define dlist_next(element)((element)->next) #define dlist_prev(element)((element)->prev) #endif
示例2: 雙向鏈表抽象數據類型的實現
/*dlist.c*/ #include <stdio.h> #include <string.h> #include "dlist.h" /*dlist_init 初始化雙向鏈表*/ void dlist_init(DList *list,void(*destroy)(void *data)) { list->size = 0; list->destroy = destroy; list->head = NULL; list->tail = NULL; return ; } /*dlist_destroy 銷毀雙向鏈表*/ void dlist_destroy(DList *list) { void *data; /*移除每一個元素*/ while(dlist_size(list)>0) { if(dlist_remove(list,dlist_tail(list),(void **)&data)==0 && list->destroy != NULL) { /*調用一個用戶自定義函數釋放動態分配的數據*/ list->destroy(data); } } /*不再允許其他操作,清除鏈表結構*/ memset(list,0,sizeof(DList)); return; } /*dlist_ins_next 將元素插入指定元素之后*/ int dlist_ins_next(DList *list,DListElmt *element,const void *data) { DListElmt *new_element; /*除非鏈表為空,否則不允許使用null元素。*/ if(element == NULL && dlist_size(list) != 0) return -1; /*為元素分配空間*/ if((new_element=(DListElmt*)malloc(sizeof(DListElmt)))==NULL) return -1; /*將新元素插入鏈表*/ new_element->data = (void*)data; if(dlist_size(list)==0) { /*鏈表為空時*/ list->head = new_element; list->head->prev = NULL; list->head->next = NULL; list->tail = new_element; } else { /*鏈表不為空時*/ new_element->next = element->next; new_element->prev = element; if(element->next == NULL) list->tail = new_element; else element->next->prev=new_element; element->next = new_element; } list->size++; return 0; } /*dlist_ins_prev*/ int dlist_ins_prev(DList *list,DListElmt *element,const void *data) { DListElmt *new_element; /*除非鏈表為空,否則不允許element為null*/ if(element == NULL && dlist_size(list)!=0) return -1; /*為新元素分配存儲*/ if((new_element=(DlistElmt *)malloc(sizeof(DListElmt))==NULL) return -1; /*insert the new element into the list*/ new_element->data=(void *data); if(dlist_size(list)==0) { /*鏈表為空*/ list->head = new_element; list->head->prev = NULL; list->tail->tail = NULL; list->tail = new_element; } else { /*鏈表非空*/ new_element_next = element; new_element_prev = element_prev; if(element->prev == NULL) list->head = new_element; else element->prev->next = new_element; element->prev = new_element; } /*改變鏈表中結點數量*/ list->size++; return 0; } /*dlist_remove*/ int dlist_remove(Dlist *list,DList_Elmt *element,void **data) { /*不允許移除一個空元素或者從一個空鏈表中移除元素.*/ if(element == NULL || dlist_size(list)==0) return -1; /*移除元素*/ *data = element->data; if(element == list->head) { /*從鏈表的頭部移除操作*/ list->head = element->next; if(list->head == NULL) list->tail = NULL; else element->next->prev = NULL; } else { /*從鏈表其他位置移除元素操作*/ element->prev->next = element->next; if(element->next == NULL) list->tail = element->prev; else element->next->prev = element->prev; } /*釋放空間*/ free(element); /*改變鏈表中結點數量*/ list->size--; return 0; }