双向循环链表,也就是在双向链表的基础上加上循环链表的特性,使其首尾相连。最后的next指针指向首元素,而首元素的pre指针指向尾元素。
如图
这里介绍双向链表的常用操作:
代码总分为三个文件:
- DLinkCircleList.h : 放置功能函数的声明,以及表的声明,表结点的定义
- DLinkCircleList.c : 放置功能函数的定义,以及表的定义
- Main.c : 主函数,使用功能函数完成各种需求,一般用作测试
整体结构图为:
这里详细说下插入操作和删除操作:
插入操作:
如图
插入元素方法:
判断表和插入位置是否合法
由表头开始通过next域移动pos次后,当前元素的next域为要插入的位置
判断是否为空表
是空表的话进行空表插入
不是空表的话判断是否为头插,如果是头插的话进行头插
不是空表且不是头插则为正常情况和尾插,则进行正常情况的插入
表长度加1
删除操作:
如图
删除元素方法:
判断表和插入位置是否合法
由表头开始通过next域移动pos次后,当前元素的next指向的元素为要删除的元素
判断长度是否为1,如果为1的话则直接清空表
判断是否为头删
是头删的话,进行头删
不是头删的话则为尾删和正常情况,则按正常情况删除
表长度减1
如果游标指向的是要删除的元素,则后移,指向next
OK! 上代码:
DLinkCircleList.h :
- #ifndef _DLINKCIRCLELIST_H_
- #define _DLINKCIRCLELIST_H_
- typedef void DLinkCircleList;
- typedef struct _tag_DLinkCircleListNode DLinkCircleListNode;
- struct _tag_DLinkCircleListNode
- {
- DLinkCircleListNode* next;
- DLinkCircleListNode* pre;
- };
- DLinkCircleList* DLinkCircleList_Create();
- void DLinkCircleList_Dstroy(DLinkCircleList* list);
- void DLinkCircleList_Clear(DLinkCircleList* list);
- int DLinkCircleList_Length(DLinkCircleList* list);
- int DLinkCircleList_Insert(DLinkCircleList* list, DLinkCircleListNode* node, int pos);
- DLinkCircleListNode* DLinkCircleList_Get(DLinkCircleList* list, int pos);
- DLinkCircleListNode* DLinkCircleList_Delete(DLinkCircleList* list, int pos);
- DLinkCircleListNode* DLinkCircleList_DeleteNode(DLinkCircleList* list, DLinkCircleListNode* node);
- DLinkCircleListNode* DLinkCircleList_Reset(DLinkCircleList* list);
- DLinkCircleListNode* DLinkCircleList_Current(DLinkCircleList* list);
- DLinkCircleListNode* DLinkCircleList_Next(DLinkCircleList* list);
- DLinkCircleListNode* DLinkCircleList_Pre(DLinkCircleList* list);
- #endif
DLinkCircleList.c :
- #include <stdio.h>
- #include <malloc.h>
- #include "DLinkCircleList.h"
- typedef struct _tag_DLinkCircleList
- {
- DLinkCircleListNode header;
- DLinkCircleListNode* slider;
- int length;
- }TDLinkCircleList;
- DLinkCircleList* DLinkCircleList_Create()
- {
- TDLinkCircleList* sList = (TDLinkCircleList*)malloc(sizeof(TDLinkCircleList));
- if(NULL != sList)
- {
- sList->header.next = NULL;
- sList->header.pre = NULL;
- sList->slider = NULL;
- sList->length = 0;
- }
- return sList;
- }
- void DLinkCircleList_Destroy(DLinkCircleList* list)
- {
- free(list);
- }
- void DLinkCircleList_Clear(DLinkCircleList* list)
- {
- TDLinkCircleList* sList = (TDLinkCircleList*)list;
- if(NULL != sList)
- {
- sList->header.next = NULL;
- sList->header.pre = NULL;
- sList->slider = NULL;
- sList->length = 0;
- }
- }
- int DLinkCircleList_Length(DLinkCircleList* list)
- {
- TDLinkCircleList* sList = (TDLinkCircleList*)list;
- int ret = -1;
- if(NULL != sList)
- {
- ret = sList->length;
- }
- return ret;
- }
- int DLinkCircleList_Insert(DLinkCircleList* list, DLinkCircleListNode* node, int pos)
- {
- TDLinkCircleList* sList = (TDLinkCircleList*)list;
- int ret = (NULL!=sList)&&(NULL!=node)&&(0<=pos);
- int i = 0;
- if(ret)
- {
- DLinkCircleListNode* current = (DLinkCircleListNode*)sList;
- DLinkCircleListNode* next = NULL;
- for(i=0; (i<pos)&&(NULL!=current->next); i++)
- {
- current = current->next;
- }
- next = current->next;
- current->next = node;
- if(0 == sList->length)
- {
- node->next = node;
- node->pre = node;
- sList->slider = node;
- }
- else
- {
- if(current == (DLinkCircleListNode*)sList)
- {
- node->next = next;
- (next->pre)->next = node;
- node->pre = next->pre;
- next->pre = node;
- }
- else
- {
- node->next = next;
- next->pre = node;
- node->pre = current;
- }
- }
- sList->length++;
- }
- return ret;
- }
- DLinkCircleListNode* DLinkCircleList_Get(DLinkCircleList* list, int pos)
- {
- TDLinkCircleList* sList = (TDLinkCircleList*)list;
- DLinkCircleListNode* ret = NULL;
- int i = 0;
- if((NULL!=sList)&&(0<=pos)&&(0<sList->length))
- {
- DLinkCircleListNode* current = (DLinkCircleListNode*)sList;
- for(i=0; (i<pos)&&(NULL!=current->next); i++)
- {
- current = current->next;
- }
- ret = current->next;
- }
- return ret;
- }
- DLinkCircleListNode* DLinkCircleList_Delete(DLinkCircleList* list, int pos)
- {
- TDLinkCircleList* sList = (TDLinkCircleList*)list;
- DLinkCircleListNode* ret = NULL;
- int i = 0;
- if((NULL!=sList)&&(0<=pos)&&(0<sList->length))
- {
- DLinkCircleListNode* current = (DLinkCircleListNode*)sList;
- DLinkCircleListNode* next = NULL;
- for(i=0; (i<pos)&&(NULL!=current->next); i++)
- {
- current = current->next;
- }
- if(1 == sList->length)
- {
- ret = sList->header.next;
- DLinkCircleList_Clear(sList);
- return ret;
- }
- ret = current->next;
- next = ret->next;
- current->next = next;
- if(current == (DLinkCircleListNode*)sList)
- {
- next->pre = ret->pre;
- (ret->pre)->next = next;
- }
- else
- {
- next->pre = current;
- }
- sList->length--;
- if(ret == sList->slider)
- {
- sList->slider = next;
- }
- }
- return ret;
- }
- DLinkCircleListNode* DLinkCircleList_DeleteNode(DLinkCircleList* list, DLinkCircleListNode* node)
- {
- TDLinkCircleList* sList = (TDLinkCircleList*)list;
- DLinkCircleListNode* ret = NULL;
- int i = 0;
- if((NULL!=sList)&&(NULL!=node))
- {
- DLinkCircleListNode* current = (DLinkCircleListNode*)sList;
- for(i=0; i<sList->length; i++)
- {
- if(node == current->next)
- {
- ret = current->next;
- break;
- }
- current = current->next;
- }
- if(NULL != ret)
- {
- DLinkCircleList_Delete(sList, i);
- }
- }
- return ret;
- }
- DLinkCircleListNode* DLinkCircleList_Reset(DLinkCircleList* list)
- {
- TDLinkCircleList* sList = (TDLinkCircleList*)list;
- DLinkCircleListNode* ret = NULL;
- if(NULL!=sList)
- {
- sList->slider = sList->header.next;
- ret = sList->slider;
- }
- return ret;
- }
- DLinkCircleListNode* DLinkCircleList_Current(DLinkCircleList* list)
- {
- TDLinkCircleList* sList = (TDLinkCircleList*)list;
- DLinkCircleListNode* ret = NULL;
- if(NULL!=sList)
- {
- ret = sList->slider;
- }
- return ret;
- }
- DLinkCircleListNode* DLinkCircleList_Next(DLinkCircleList* list)
- {
- TDLinkCircleList* sList = (TDLinkCircleList*)list;
- DLinkCircleListNode* ret = NULL;
- if((NULL!=sList)&&(NULL!=sList->slider))
- {
- ret = sList->slider;
- sList->slider = ret->next;
- }
- return ret;
- }
- DLinkCircleListNode* DLinkCircleList_Pre(DLinkCircleList* list)
- {
- TDLinkCircleList* sList = (TDLinkCircleList*)list;
- DLinkCircleListNode* ret = NULL;
- if((NULL!=sList)&&(NULL!=sList->slider))
- {
- ret = sList->slider;
- sList->slider = ret->pre;
- }
- return ret;
- }
Main.c :
- #include <stdio.h>
- #include <stdlib.h>
- #include "DLinkCircleList.h"
- typedef struct _tag_Value
- {
- DLinkCircleListNode header;
- int v;
- }Value;
- int main(void)
- {
- DLinkCircleList* list = DLinkCircleList_Create();
- Value v1,v2,v3,v4,v5;
- Value* pV = NULL;
- int i = 0;
- v1.v=1, v2.v=2, v3.v=3, v4.v=4, v5.v=5;
- DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v1, DLinkCircleList_Length(list));
- DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v2, DLinkCircleList_Length(list));
- DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v3, DLinkCircleList_Length(list));
- DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v4, DLinkCircleList_Length(list));
- DLinkCircleList_Insert(list, (DLinkCircleListNode*)&v5, DLinkCircleList_Length(list));
- for(i=0; i<DLinkCircleList_Length(list); i++)
- {
- pV = (Value*)DLinkCircleList_Get(list, i);
- printf("已发现节点:%d\n", pV->v);
- }
- printf("\n");
- DLinkCircleList_Delete(list, 0);
- DLinkCircleList_DeleteNode(list, &v3);
- DLinkCircleList_Destroy(list);
- return 0;
- }