数据结构 链表_双向链表的实现与分析
双向链表的实现与分析
双向链表的组成 :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; }