一、单向链表的局限:单向链表的节点都只有一个指向下一个节点的指针;单向链表的数据元素无法直接访问其前驱元素;逆序访问单向链表中的元素是极其耗时的操作。
二、双向链表的定义:在单向链表的结点基础上增加一个指向其前驱的pre指针。
三、双向链表的所有操作:
1. 创建链表
2. 销毁链表
3. 获取链表的长度
4. 清空链表
5. 获取第pos个元素
6. 插入元素到位置pos
7. 删除位置pos处的元素
双向链表新增操作:
1. 获取当前游标指向的数据元素
2. 将游标重置指向链表中的第一个数据元素
3. 将游标移动指向到链表中的上一个数据元素
4. 将游标移动指向到链表中的下一个数据元素
5. 直接指定删除链表中的某个数据元素
四、优缺点:
优点:双向链表在单向链表的基础上增加了指向前驱的指针,功能上双向链表可以完全取代单链表的使用,双向链表可以高效的遍历链表中的所有元素。
缺点:代码复杂度提高。
五、插入与删除:
六、设计与实现
#ifndef _ZCH_DLINKLIST_H_ #define _ZCH_DLINKLIST_H_ typedef void DLinkList; typedef struct _tag_DLinkListNode { struct _tag_DLinkListNode* next; struct _tag_DLinkListNode * pre; }DLinkListNode; DLinkList* Create(); void Destroy(DLinkList* list); void Clear(DLinkList* list); int Length(DLinkList* list); int Insert(DLinkList* list, DLinkListNode* node, int pos); DLinkListNode* GetEle(DLinkList* list, int pos); DLinkListNode* Delete(DLinkList* list, int pos); //add DLinkListNode* DeleteNode(DLinkList* list, DLinkListNode* node); DLinkListNode* Reset(DLinkList* list); DLinkListNode* Current(DLinkList* list); DLinkListNode* Next(DLinkList* list); DLinkListNode* Pre(DLinkList* list); #endif
#include <stdio.h> #include <malloc.h> #include "zch_dlinklist.h" typedef struct _tag_DLinkList { DLinkListNode header; DLinkListNode* slider; int length; }TDLinkList; DLinkList* Create() { TDLinkList* ret = (TDLinkList*)malloc(sizeof(TDLinkList)); if(ret != NULL) { ret->length = 0; ret->header.next = NULL; ret->header.pre = NULL; ret->slider = NULL; } return ret; } void Destory(DLinkList* list) { if(list != NULL) { free(list); } } void Clear(DLinkList* list) { TDLinkList* dList = (TDLinkList*)list; if(dList != NULL) { dList->length = 0; dList->header.next = NULL; dList->header.pre = NULL; dList->slider = NULL; } } int Length(DLinkList* list) { TDLinkList* dList = (TDLinkList*)list; if(NULL == dList) { return -1; } return dList->length; } int Insert(DLinkList* list, DLinkListNode* node, int pos) { int i = 0; TDLinkList* dList = (TDLinkList*)list; if(dList == NULL || node == NULL || pos < 0) { return -1; } //指向头节点 DLinkListNode* current = (DLinkListNode*)dList; //需增加第二个辅助指针 DLinkListNode* node = NULL; for(i = 0; (i < pos) && (current->next != NULL); i++) { current = current->next; } next = current->next; current->next = node; node->next = next; if(next != NULL) { next->pre = node; } node->pre = current; if(dList->length == 0) { dList->slider = node;//插入第一个元素的时候,游标指向第一个元素 } //若在0位置插入 if(current == (DLinkListNode*)dList) { node->pre = NULL; } dList->length++; return 0; } DLinkListNode* GetEle(DLinkList* list, int pos) { TDLinkList* dList = (TDLinkList*)list; DLinkListNode* ret = NULL; int i = 0; if((dList != NULL) && (0 <= pos) && (pos < dList->length)) { DLinkListNode* current = (DLinkListNode*)dList; for(i = 0; i < pos; i++) { current = current->next; } ret = current->next; } return ret; } DLinkListNode* Delete(DLinkList* list, int pos) { TDLinkList* dList = (TDLinkList*)list; DLinkListNode* ret = NULL; int i = 0; if(dList == NULL || pos < 0) { return NULL; } DLinkListNode* current = (DLinkListNode*)dList; DLinkListNode* next = NULL; for(i = 0; i < pos; i++) { current = current->next; } ret = current->next; next = ret->next; current->next = next; if(next != NULL) { next->pre = current; if(current == (DLinkListNode*)dList) { next->pre = NULL; } } if(dList->slider == ret) { dList->slider = next; } dList->length--; return ret; } DLinkListNode* DeleteNode(DLinkList* list, DLinkListNode* node) { TDLinkList* dList = (TDLinkList*)list; DLinkListNode* ret = NULL; int i = 0; if(dList != NULL) { DLinkListNode* current = (DLinkListNode*)dList; for(i = 0; i < dList->length; i++) { if(current->next == node) { ret = current->next; break; } current = current->next; } if(ret != NULL) { Delete(dList, i); } } return ret; } DLinkListNode* Reset(DLinkList* list) { TDLinkList* dList = (TDLinkList*)list; DLinkListNode* ret = NULL; if(dList != NULL) { dList->slider = dList->header.next; ret = dList->slider; } return ret; } DLinkListNode* Current(DLinkList* list) { TDLinkList* dList = (TDLinkList*)list; DLinkListNode* ret = NULL; if(dList != NULL) { ret = dList->slider; } return ret; } DLinkListNode* Next(DLinkList* list) { TDLinkList* dList = (TDLinkList*)list; DLinkListNode* ret = NULL; if((dList != NULL) && (dList->slider != NULL)) { ret = dList->slider; dList->slider = ret->next; } return ret; } DLinkListNode* Pre(DLinkList* list) { TDLinkList* dList = (TDLinkList*)list; DLinkListNode* ret = NULL; if((dList != NULL) && (dList->slider != NULL)) { ret = dList->slider; dList->slider = ret->pre; } return ret; }