数据结构(18)双向循环链表
2015-08-11 14:49
711 查看
双向循环链表,也就是在双向链表的基础上加上循环链表的特性,使其首尾相连。最后的next指针指向首元素,而首元素的pre指针指向尾元素。
如图
这里介绍双向链表的常用操作:
l 创建双向链表
l 销毁双向链表
l 清空双向链表
l 获取表长度
l 把node插入pos位置
l 获取pos位置的元素
l 删除pos位置的元素
l 删除表中与node相同的元素(删除第一个匹配成功的)
l 重置游标
l 返回游标所指向的结点
l 游标后移
l 游标前移
代码总分为三个文件:
DLinkCircleList.h : 放置功能函数的声明,以及表的声明,表结点的定义
DLinkCircleList.c : 放置功能函数的定义,以及表的定义
Main.c : 主函数,使用功能函数完成各种需求,一般用作测试
整体结构图为:
这里详细说下插入操作和删除操作:
插入操作:
如图
插入元素方法:
判断表和插入位置是否合法
由表头开始通过next域移动pos次后,当前元素的next域为要插入的位置
判断是否为空表
是空表的话进行空表插入
不是空表的话判断是否为头插,如果是头插的话进行头插
不是空表且不是头插则为正常情况和尾插,则进行正常情况的插入
表长度加1
删除操作:
如图
删除元素方法:
判断表和插入位置是否合法
由表头开始通过next域移动pos次后,当前元素的next指向的元素为要删除的元素
判断长度是否为1,如果为1的话则直接清空表
判断是否为头删
是头删的话,进行头删
不是头删的话则为尾删和正常情况,则按正常情况删除
表长度减1
如果游标指向的是要删除的元素,则后移,指向next
OK! 上代码:
DLinkCircleList.h :
[cpp] view
plaincopy
#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 :
[cpp] view
plaincopy
#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 :
[cpp] view
plaincopy
#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;
}
如图
这里介绍双向链表的常用操作:
l 创建双向链表
l 销毁双向链表
l 清空双向链表
l 获取表长度
l 把node插入pos位置
l 获取pos位置的元素
l 删除pos位置的元素
l 删除表中与node相同的元素(删除第一个匹配成功的)
l 重置游标
l 返回游标所指向的结点
l 游标后移
l 游标前移
代码总分为三个文件:
DLinkCircleList.h : 放置功能函数的声明,以及表的声明,表结点的定义
DLinkCircleList.c : 放置功能函数的定义,以及表的定义
Main.c : 主函数,使用功能函数完成各种需求,一般用作测试
整体结构图为:
这里详细说下插入操作和删除操作:
插入操作:
如图
插入元素方法:
判断表和插入位置是否合法
由表头开始通过next域移动pos次后,当前元素的next域为要插入的位置
判断是否为空表
是空表的话进行空表插入
不是空表的话判断是否为头插,如果是头插的话进行头插
不是空表且不是头插则为正常情况和尾插,则进行正常情况的插入
表长度加1
删除操作:
如图
删除元素方法:
判断表和插入位置是否合法
由表头开始通过next域移动pos次后,当前元素的next指向的元素为要删除的元素
判断长度是否为1,如果为1的话则直接清空表
判断是否为头删
是头删的话,进行头删
不是头删的话则为尾删和正常情况,则按正常情况删除
表长度减1
如果游标指向的是要删除的元素,则后移,指向next
OK! 上代码:
DLinkCircleList.h :
[cpp] view
plaincopy
#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 :
[cpp] view
plaincopy
#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 :
[cpp] view
plaincopy
#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;
}
相关文章推荐
- 数据结构(17)双向链表
- 数据结构(16)循环链表
- 数据结构实验之栈一:进制转换 SDUT 2131
- 数据结构07:查找
- 数据结构实验之链表四:有序链表的归并
- 【数据结构】基本概念
- 数据结构:define实现链表
- 数据结构实验之链表三:链表的逆置
- 数据结构实验之链表二:逆序建立链表
- 数据结构实验之链表一:顺序建立链表
- 数据结构_选择排序
- (原创)数据结构---树(Python)
- 链队列
- C源码@数据结构与算法->表(Cursor )
- 深入理解Cocos2d-x 3.x:内置数据结构(2)Map
- 数据结构_希尔排序(分组加直接插入排序)
- HDU2193-AVL-数据结构-AVL
- 【黑马程序员-学习笔记】数据结构-树与图
- 数据结构学习笔记4-最长回文子串(Manacher算法)
- 数据结构-----线段树(一)