一、循环链表的定义:将单链表中最后一个数据元素的next指针指向第一个元素。
二、循环链表的操作:循环链表拥有单链表的所有操作。
1. 创建链表
2. 销毁链表
3. 获取链表的长度
4. 清空链表
5. 获取pos位置的元素
6. 插入元素到pos位置
7. 删除pos位置的元素
三、游标的定义(新增的功能)
在循环链表中可以定义一个“当前指针”,通常将这个指针称为游标,可以通过这个游标来遍历循环链表中的所有元素。
四、循环链表的新操作
1. 获取循环链表当前游标指向的数据元素
2. 将游标重置指向链表中的第一个数据元素
3. 将游标移动指向到链表中的下一个数据元素
4. 直接指定删除链表中的某个数据元素
五、插入元素分析,分为第一次插入元素、普通位置插入和特殊位置插入(头插、尾插)。
六、删除元素分析
七、循环链表的优缺点
优点:循环链表在功能上比单链表强,循环链表完全可以取代单链表,循环链表可以高效的遍历表中的元素。
缺点:代码实现的复杂度提高了
八、循环链表的典型应用
约瑟夫问题:n 个人围成一个圆圈,首先第 1 个人从 1 开始一个人一个人顺时针报数,报到第 m 个人,令其出列。然后再从下一个人开始从 1 顺时针报数,报到第 m 个人,再令其出列,…,如此下去,求出列顺序。
九、循环链表的api设计
//头文件
#ifndef _ZCH_CIRCLELIST_H_
#define _ZCH_CIRCLELIST_H_
typedef void CircleList //数据封装
//循环链表的指针域
typedef struct _tag_CircleListNode
{
struct _tag_CircleListNode *next;
}CircleListNode;
CircleList* Create();
void Destroy(CircleList* list);
void Clear(CircleList* list);
int Length(CircleList* list);
int Insert(CiecleList* list, CircleListNode* node, int pos);
CircleListNode* GetEle(CircleList* list , int pos);
CircleListNode* Delete(CircleList* list, int pos);
//增加功能
CircleListNode* DeleteNode(CircleList* list, CircleListNode* node);
CircleListNode* Reset(CircleList* list);
CircleListNode* Current(CircleList* list);
CircleListNode* Next(CircleList* list);
#endif
十、循环链表api的实现
#include "zch_circlelist.h"
//循环链表的抽象
typedef struct _tag_CircleList
{
//头节点
CircleListNode header;
//游标
CircleListNode* slider;
int length;
} TCircleList;
CircleList* Create()
{
TCircleList* CList = (TCircleList*)malloc(sizeof(TCircleList));
if(NULL == CList)
{
return NULL;
}
CList->length = 0;
CList->header.next = NULL;
CList->slider = NULL;
return CList;
}
void Destroy(CircleList* list)
{
if (list == NULL)
{
return ;
}
free(list);
}
void Clear(CircleList* list)
{
TCircleList* CList = (TCircleList*)list;
if(NULL == CList)
{
return ;
}
CList->length = 0;
CList->hender.next = NULL;
CList->slider = NULL;
}
int Length(CircleList* list)
{
TCircleList* CList = (TCircleList*)list;
if (list == NULL)
{
return -1;
}
return CList->length;
}
int Insert(CircleList* list, CircleListNode* node, int pos)
{
int i = 0;
TCircleList* CList = (TCircleList*)list;
//辅助指针current指向头节点
CircleListNode* current = (CircleListNode*)CList;
if(NULL == CList || NULL == node || pos < 0)
{
return -1
}
if(pos >= CList->length)
{
pos = CList->length; //默认尾插
}
for(i = 0; (i < pos) && (current->next != NULL); i++)
{
current = current->next;
}
node->next = current->next;
current->next = node;
//若是第一次插入节点
if(CList->length == 0)
{
//游标指向第0号元素
CList->slider = node;
}
CList->length++;
//若是头插法
if(current == (CircleListNode*)CList)
{
CircleListNode* last = GetEle(CList, CList->length - 1);
last->next = current->next; //指向0号元素,形成循环
}
return 0;
}
CircleListNode* GetEle(CircleList* list, int pos)
{
TCircleList* CList = (TCircleList*)list;
CircleListNode* current = (CircleListNode*)CList;
int i = 0;
if(NULL == CList || pos < 0 || pos >= CList->length)
{
return NULL;
}
for(i = 0; i < pos; i++)
{
current = current->next;
}
return current->next;
}
CircleListNode* Delete(CircleList* list, int pos)
{
TCircleList* CList = (TCircleList*)list;
CircleListNode* ret = NULL;
int i = 0;
if((CList != NULL) && (pos >= 0) && (CList->length > 0) && (pos < CList->length))
{
CircleListNode* current = (CircleListNode*)CList;
CircleListNode* last = NULL;
for(i = 0; i < pos; i++)
{
current = current->next;
}
//若删除第一个元素
if(current == (CircleListNode*)CList)
{
last = GetEle(CList, CList->length - 1);
}
//先将要删除的元素保存下来
ret = current->next;
current->next = ret->next;
CList->length--;
//头删
if(last)
{
CList->header.next = ret->next;
last->next = ret->next;
}
//若删除的元素为游标所指的元素
if(CList->slider == ret)
{
CList->slider = ret->next;
}
//若删除元素后,链表的长度为0
if(CList->length == 0)
{
CList->header.next = NULL;
CList->slider = NULL;
}
}
return ret;
}
CircleListNode* DeleteNode(CircleList* list, CircleListNode* node)
{
TCircleList* CList = (TCircleList*)list;
CircleListNode* ret = NULL;
int i = 0;
if(CList != NULL)
{
CircleListNode* current = (CircleListNode*)CList;
for(i = 0; i <CList->length; i++)
{
//查找node在循环链表中的位置i
if(current->next == node)
{
ret = current->next;
break;
}
current = current->next;
}
//如果ret找到,根据i去是删除
if(ret != NULL)
{
Delete(CList, i);
}
}
return ret;
}
CircleListNode* Reset(CircleList* list)
{
TCircleList* CList = (TCircleList*)list;
CircleListNode* ret = NULL;
if(CList != NULL)
{
CList->slider = CList->header.next;
ret = CList->slider;
}
return ret;
}
CircleListNode* Current(CircleList* list)
{
TCircleList* CList = (TCircleList)list;
CircleListNode* ret = NULL;
if(CList != NULL)
{
ret = CList->slider;
}
return ret;
}
CircleListNode* Next(CircleList* list)
{
TCircleList* CList = (TCircleList*)list;
CircleListNode* ret = NULL;
if((CList != NULL) && (CList->slider != NULL))
{
ret = CList->slider;
CList->slider = ret->next;
}
return ret;
}