循环链表插入元素的思想图:
尾插法时候,有点不一样:需要处理
循环链表
1、基本概念
循环链表的定义:将单链表中最后一个数据元素的next指针指向第一个元素
循环链表拥有单链表的所有操作
创建链表
销毁链表
获取链表长度
清空链表
获取第pos个元素操作
插入元素到位置pos
删除位置pos处的元素
新增功能:游标的定义
在循环链表中可以定义一个“当前”指针,这个指针通常称为游标,可以通过这个游标来遍历链表中的所有元素。
循环链表新操作
获取当前游标指向的数据元素
将游标重置指向链表中的第一个数据元素
将游标移动指向到链表中的下一个数据元素
直接指定删除链表中的某个数据元素
CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node);
CircleListNode* CircleList_Reset(CircleList* list);
CircleListNode* CircleList_Current(CircleList* list);
CircleListNode* CircleList_Next(CircleList* list);
循环链表的删除操作:
//CircleList.h #ifndef _CIRCLELIST_H_ #define _CIRCLELIST_H_ //循环链表的存储结构 //结点中包含后继结点的地址的指针域可以理解为指向下一个结构体(结点) //(这里不包含数据域,是实现了 链表的api(链表的算法) 和 具体的数据分离) typedef struct _tag_CircleListNode { struct _tag_CircleListNode *next; }CircleListNode; //为void 再重新多取一个名字,CircleList等价于void //typedef + 已有的数据类型+新的数据类型(自己取的新名字) typedef void CircleList; //创建并且返回一个空的循环链表 CircleList* CircleList_Create(); //销毁一个循环链表list void CircleList_Destroy(CircleList* list); //将一个循环链表list中的所有元素清空, 循环链表回到创建时的初始状态 void CircleList_Clear(CircleList* list); //返回一个循环链表list中的元素个数 int CircleList_Length(CircleList* list); //向一个循环链表list的pos位置处插入元素 int CircleList_Insert(CircleList* list, CircleListNode* node, int pos); //获取一个循环链表list中pos位置处的元素 CircleListNode* CircleList_Get(CircleList* list, int pos); //删除一个循环链表list中pos位置处的元素,返回值为被删除的元素,NULL表示删除失败 CircleListNode* CircleList_Delete(CircleList* list, int pos); //add //直接指定删除链表中的某个数据元素 CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node); //将游标重置指向链表中的第一个数据元素 CircleListNode* CircleList_Reset(CircleList* list); //获取当前游标指向的数据元素 CircleListNode* CircleList_Current(CircleList* list); //将游标移动指向到链表中的下一个数据元素 CircleListNode* CircleList_Next(CircleList* list); #endif
//CircleList.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "CircleList.h"
//定义循环链表的头结点 循环链表头结点:表示链表中第一个节点,包含指向第一个数据元素的指针以及链表自身的一些信息
//这样能把所有结点串起来
typedef struct _tag_CircleList
{
CircleListNode header; //要有个头指针---指向头结点的指针
CircleListNode *slider;//在循环链表中可以定义一个“当前指针”,这个指针通常称为游标,可以通过游标来遍历链表中所有元素
int length;//链表的长度
}TCircleList;
//创建并且返回一个空的循环链表
CircleList* CircleList_Create()
{
//1 申请动态内存空间
TCircleList *tmp = (TCircleList *)malloc(sizeof(TCircleList));
if (NULL == tmp)
{
printf("func err malloc:%d\n");
return NULL;
}
//2 让开辟的内存 完成链式线性表初始化
memset(tmp, 0, sizeof(TCircleList));
//3 链表的初始化
tmp->header.next = NULL;
tmp->slider = NULL;
tmp->length = 0;
return tmp;
}
//销毁一个循环链表list
void CircleList_Destroy(CircleList* list)
{
//1 缓存下来 进行操作
TCircleList *tmp = NULL;
tmp = (TCircleList *)list;
if (NULL == list)
{
printf("func err CircleList_Destroy()\n");
}
//2 释放头结点空间
if (tmp != NULL)
{
free(tmp);
}
}
//将一个循环链表list中的所有元素清空, 循环链表回到创建时的初始状态
void CircleList_Clear(CircleList* list)
{
//1 缓存下来 进行操作
TCircleList *tmp = NULL;
tmp = (TCircleList *)list;
if (NULL == list)
{
printf("func err CircleList_Clear()\n");
}
//2 清空链表
tmp->header.next = NULL;
tmp->slider = NULL;
tmp->length = 0;
}
//返回一个循环链表list中的元素个数
int CircleList_Length(CircleList* list)
{
int ret = 0;
//1 缓存下来 进行操作
TCircleList *tmp = NULL;
tmp = (TCircleList *)list;
if (NULL == list)
{
ret = -1;
printf("func err CircleList_Length():%d\n", ret);
return ret;
}
ret = tmp->length;
return ret;
}
//向一个循环链表list的pos位置处插入元素
int CircleList_Insert(CircleList* list, CircleListNode* node, int pos)
{
int ret = 0;
//1 缓存下来 进行操作
TCircleList *tmp = NULL;
tmp = (TCircleList *)list;
//辅助指针 用来遍历当前指针位置
CircleListNode *pCur = NULL;
if (NULL == list || NULL == node || pos < 0)
{
ret = -1;
printf("func err (NULL == list || NULL == node || pos < 0):%d\n", ret);
return ret;
}
//1 当前指针 初始化 指向 头结点
pCur = &(tmp->header);
//2 进行遍历 找到插入位置
for (int i = 0; i < pos&&(pCur->next!=NULL); i++)
{
pCur = pCur->next;
}
//3 进行插入操作
node->next = pCur->next;//1
pCur->next = node;//2
//若第一次插入结点 让游标指向0号结点
if (tmp->length == 0)
{
tmp->slider = node;
}
//4 链表长度++
tmp->length++;
//若是头插法 pCur依然指向头结点
if (pCur == ((CircleListNode*)tmp))
{
//获取最后一个元素
CircleListNode *last = CircleList_Get(tmp,tmp->length-1);
last->next = pCur->next;//last->next = node;
}
return ret;
}
//获取一个循环链表list中pos位置处的元素
CircleListNode* CircleList_Get(CircleList* list, int pos)
{
//1 缓存下来 进行操作
TCircleList *tmp = (TCircleList *)list;
//辅助指针 用来遍历当前指针位置
CircleListNode *pCur = NULL;
if (NULL == list || pos<0)
{
printf("func err CircleList_Get\n");
return NULL;
}
//2 当前指针 初始化 指向 头结点
pCur = &(tmp->header);
//3 搜索要获得的结点
for (int i = 0; i < pos && (tmp->length > 0); i++)
{
pCur = pCur->next;
}
return pCur->next;
}
//删除一个循环链表list中pos位置处的元素,返回值为被删除的元素,NULL表示删除失败
CircleListNode* CircleList_Delete(CircleList* list, int pos)
{
//1 缓存下来 进行操作
TCircleList *tmp = (TCircleList *)list;
//辅助指针 用来遍历当前指针位置
CircleListNode *pCur = NULL;
//辅助指针 用来缓存最后一个元素
CircleListNode *last = NULL;
//辅助指针 用来缓存删除元素
CircleListNode *DeletNode = NULL;
if (NULL == list || pos < 0 || 0 == tmp->length)
{
printf("func err CircleList_Delete\n");
return NULL;
}
//2 当前指针 初始化 指向 头结点
pCur = &(tmp->header);
//3 搜索要获得的结点
for (int i = 0; i < pos && (tmp->length > 0); i++)
{
pCur = pCur->next;
}
//若头部删除时候 pCur依然指向头结点
if (pCur == ((CircleListNode *)tmp))
{
//h获取最后一个元素
last = CircleList_Get(tmp,tmp->length-1);
}
//4 缓存删除元素
DeletNode = pCur->next;
//5 连接 删除结点操作
pCur->next = DeletNode->next;//1
//6 链表长度--
tmp->length--;
//7 判断last是否为空
if (last!=NULL)
{
last->next = DeletNode->next;//2
}
//8 若删除元素为游标所指元素 需要后移
if (tmp->slider == DeletNode)
{
tmp->slider = DeletNode->next;
}
//9 若删除元素后链表长度为0
if (tmp->length == 0)
{
tmp->header.next = NULL;
tmp->slider = NULL;
}
return DeletNode;
}
//add
//直接指定删除链表中的某个数据元素
CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node)
{
//1 缓存下来 进行操作
TCircleList *tmp = (TCircleList *)list;
//辅助指针 用来遍历当前指针位置
CircleListNode *pCur = NULL;
//辅助指针 用来缓存删除元素
CircleListNode *DeletNode = NULL;
if (NULL == list || 0 == node || 0 == tmp->length)
{
printf("func err CircleList_DeleteNode\n");
return NULL;
}
//2 当前指针 初始化 指向 头结点
pCur = &(tmp->header);
//3 搜索要获得的结点
int i;
for ( i = 0; i < tmp->length; i++)
{
if (pCur->next == node)//根据删除结点搜索到要删除位置
{
DeletNode = pCur->next;//缓存删除元素
break;//这里搜索到要删除的结点,结束循环,否则会报错
} pCur = pCur->next; } //4 根据pos位置删除元素 if (DeletNode != NULL) { CircleList_Delete(tmp,i); } return DeletNode; } //将游标重置指向链表中的第一个数据元素 CircleListNode* CircleList_Reset(CircleList* list) { //1 缓存下来 进行操作 TCircleList *tmp = (TCircleList *)list; //辅助指针 用来缓存重置游标位置 CircleListNode *tmpReset = NULL; if (NULL == list) { printf("func err CircleList_Reset\n"); return NULL; } if (tmp!=NULL) { tmp->slider = tmp->header.next;//重置指向第一个数据元素 tmpReset = tmp->slider;//缓存游标位置 } return tmpReset; } //获取当前游标指向的数据元素 CircleListNode* CircleList_Current(CircleList* list) { //1 缓存下来 进行操作 TCircleList *tmp = (TCircleList *)list; //辅助指针 用来缓存当前游标位置 CircleListNode *tmpCur = NULL; if (NULL == list) { printf("func err CircleList_Current\n"); return NULL; } if (tmp!=NULL) { tmpCur = tmp->slider;//缓存当前游标位置 } return tmpCur; } //将游标移动指向到链表中的下一个数据元素 CircleListNode* CircleList_Next(CircleList* list) { //1 缓存下来 进行操作 TCircleList *tmp = (TCircleList *)list; //辅助指针 用来缓存游标位置 CircleListNode *tmpNext = NULL; if (NULL == list) { printf("func err CircleList_Next\n"); return NULL; } if (tmp != NULL) { tmpNext = tmp->slider;//缓存当前游标位置 tmp->slider = tmpNext->next;//将游标下移 } return tmpNext; }
//循环链表的设计与实现测试框架 //text.c #include <stdlib.h> #include <string.h> #include <stdio.h> #include "CircleList.h"//c里面.h和.cpp没有差别 但是c++里如果模块化编程,两个头文件都必须包含进来 //业务节点示例 typedef struct Teacher { CircleListNode node;//包含指针域节点 //下面是业务域 int age; }Teacher; int main() { int len = 0; int ret = 0; int pos = 0; CircleList *Cirtmp = NULL; Teacher t1, t2, t3, t4; t1.age = 10; t2.age = 11; t3.age = 12; t4.age = 13; Cirtmp = CircleList_Create(); if (NULL == Cirtmp) { ret = -1; printf("func err CircleList_Create():%d\n,", ret); return ret; } len = CircleList_Length(Cirtmp); if (len < 0) { ret = -2; printf("func err CircleList_Length():%d\n", ret); return ret; } //循环链表的算法 和具体的业务结点 分离 //int CircleList_Insert(CircleList* list, CircleListNode* node, int pos) ret = CircleList_Insert(Cirtmp, (CircleListNode *)(&t1), 0); ret = CircleList_Insert(Cirtmp, (CircleListNode *)(&t2), 0); ret = CircleList_Insert(Cirtmp, (CircleListNode *)(&t3), 0); ret = CircleList_Insert(Cirtmp, (CircleListNode *)(&t4), 0); //遍历 for (int i = 0; i < 2 * CircleList_Length(Cirtmp); i++) { Teacher *tmp = (Teacher *)CircleList_Get(Cirtmp, i); if (NULL == tmp) { ret = -3; printf("func err CircleList_Get():%d\n", ret); return ret; } printf("tmp->age:%d\t", tmp->age); } printf("\n================================我是分界线===============================\n"); while (CircleList_Length(Cirtmp) > 0) { Teacher *tmp = (Teacher *)CircleList_Delete(Cirtmp, 0); if (NULL == tmp) { ret = -4; printf("func err CircleList_Delete():%d\n", ret); return ret; } printf("tmp->age:%d\t", tmp->age); } printf("\n================================我是分界线===============================\n"); CircleList_Destroy(Cirtmp); system("pause"); return; }
约瑟夫问题-循环链表典型应用
n 个人围成一个圆圈,首先第 1 个人从 1 开始一个人一个人顺时针报数,报到第 m 个人,令其出列。然后再从下一 个人开始从 1 顺时针报数,报到第 m 个人,再令其出列,…,如此下去,求出列顺序。约瑟夫问题-循环链表典型应用
n 个人围成一个圆圈,首先第 1 个人从 1 开始一个人一个人顺时针报数,报到第 m 个人,令其出列。然后再从下一 个人开始从 1 顺时针报数,报到第 m 个人,再令其出列,…,如此下去,求出列顺序。
代码如下:
//CircleList.h #ifndef _CIRCLELIST_H_ #define _CIRCLELIST_H_ //循环链表的存储结构 //结点中包含后继结点的地址的指针域可以理解为指向下一个结构体(结点) //(这里不包含数据域,是实现了 链表的api(链表的算法) 和 具体的数据分离) typedef struct _tag_CircleListNode { struct _tag_CircleListNode *next; }CircleListNode; //为void 再重新多取一个名字,CircleList等价于void //typedef + 已有的数据类型+新的数据类型(自己取的新名字) typedef void CircleList; //创建并且返回一个空的循环链表 CircleList* CircleList_Create(); //销毁一个循环链表list void CircleList_Destroy(CircleList* list); //将一个循环链表list中的所有元素清空, 循环链表回到创建时的初始状态 void CircleList_Clear(CircleList* list); //返回一个循环链表list中的元素个数 int CircleList_Length(CircleList* list); //向一个循环链表list的pos位置处插入元素 int CircleList_Insert(CircleList* list, CircleListNode* node, int pos); //获取一个循环链表list中pos位置处的元素 CircleListNode* CircleList_Get(CircleList* list, int pos); //删除一个循环链表list中pos位置处的元素,返回值为被删除的元素,NULL表示删除失败 CircleListNode* CircleList_Delete(CircleList* list, int pos); //add //直接指定删除链表中的某个数据元素 CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node); //将游标重置指向链表中的第一个数据元素 CircleListNode* CircleList_SliderReset(CircleList* list); //获取当前游标指向的数据元素 CircleListNode* CircleList_SliderCurrent(CircleList* list); //将游标移动指向到链表中的下一个数据元素 CircleListNode* CircleList_SliderNext(CircleList* list); #endif
//CircleList.c #include <stdlib.h> #include <string.h> #include <stdio.h> #include "CircleList.h" //定义循环链表的头结点 循环链表头结点:表示链表中第一个节点,包含指向第一个数据元素的指针以及链表自身的一些信息 //这样能把所有结点串起来 typedef struct _tag_CircleList { CircleListNode header; //要有个头指针---指向头结点的指针 CircleListNode *slider;//在循环链表中可以定义一个“当前指针”,这个指针通常称为游标,可以通过游标来遍历链表中所有元素 int length;//链表的长度 }TCircleList; //创建并且返回一个空的循环链表 CircleList* CircleList_Create() { //1 申请动态内存空间 TCircleList *tmp = (TCircleList *)malloc(sizeof(TCircleList)); if (NULL == tmp) { printf("func err malloc:%d\n"); return NULL; } //2 让开辟的内存 完成链式线性表初始化 memset(tmp, 0, sizeof(TCircleList)); //3 链表的初始化 tmp->header.next = NULL; tmp->slider = NULL; tmp->length = 0; return tmp; } //销毁一个循环链表list void CircleList_Destroy(CircleList* list) { //1 缓存下来 进行操作 TCircleList *tmp = NULL; tmp = (TCircleList *)list; if (NULL == list) { printf("func err CircleList_Destroy()\n"); } //2 释放头结点空间 if (tmp != NULL) { free(tmp); } } //将一个循环链表list中的所有元素清空, 循环链表回到创建时的初始状态 void CircleList_Clear(CircleList* list) { //1 缓存下来 进行操作 TCircleList *tmp = NULL; tmp = (TCircleList *)list; if (NULL == list) { printf("func err CircleList_Clear()\n"); } //2 清空链表 tmp->header.next = NULL; tmp->slider = NULL; tmp->length = 0; } //返回一个循环链表list中的元素个数 int CircleList_Length(CircleList* list) { int ret = 0; //1 缓存下来 进行操作 TCircleList *tmp = NULL; tmp = (TCircleList *)list; if (NULL == list) { ret = -1; printf("func err CircleList_Length():%d\n", ret); return ret; } ret = tmp->length; return ret; } //向一个循环链表list的pos位置处插入元素 int CircleList_Insert(CircleList* list, CircleListNode* node, int pos) { int ret = 0; //1 缓存下来 进行操作 TCircleList *tmp = NULL; tmp = (TCircleList *)list; //辅助指针 用来遍历当前指针位置 CircleListNode *pCur = NULL; if (NULL == list || NULL == node || pos < 0) { ret = -1; printf("func err (NULL == list || NULL == node || pos < 0):%d\n", ret); return ret; } //1 当前指针 初始化 指向 头结点 pCur = &(tmp->header); //2 进行遍历 找到插入位置 for (int i = 0; i < pos&&(pCur->next!=NULL); i++) { pCur = pCur->next; } //3 进行插入操作 node->next = pCur->next;//1 pCur->next = node;//2 //若第一次插入结点 让游标指向0号结点 if (tmp->length == 0) { tmp->slider = node; } //4 链表长度++ tmp->length++; //若是头插法 pCur依然指向头结点 if (pCur == ((CircleListNode*)tmp)) { //获取最后一个元素 CircleListNode *last = CircleList_Get(tmp,tmp->length-1); last->next = pCur->next;//last->next = node; } return ret; } //获取一个循环链表list中pos位置处的元素 CircleListNode* CircleList_Get(CircleList* list, int pos) { //1 缓存下来 进行操作 TCircleList *tmp = (TCircleList *)list; //辅助指针 用来遍历当前指针位置 CircleListNode *pCur = NULL; if (NULL == list || pos<0) { printf("func err CircleList_Get\n"); return NULL; } //2 当前指针 初始化 指向 头结点 pCur = &(tmp->header); //3 搜索要获得的结点 for (int i = 0; i < pos && (tmp->length > 0); i++) { pCur = pCur->next; } return pCur->next; } //删除一个循环链表list中pos位置处的元素,返回值为被删除的元素,NULL表示删除失败 CircleListNode* CircleList_Delete(CircleList* list, int pos) { //1 缓存下来 进行操作 TCircleList *tmp = (TCircleList *)list; //辅助指针 用来遍历当前指针位置 CircleListNode *pCur = NULL; //辅助指针 用来缓存最后一个元素 CircleListNode *last = NULL; //辅助指针 用来缓存删除元素 CircleListNode *DeletNode = NULL; if (NULL == list || pos < 0 || 0 == tmp->length) { printf("func err CircleList_Delete\n"); return NULL; } //2 当前指针 初始化 指向 头结点 pCur = &(tmp->header); //3 搜索要获得的结点 for (int i = 0; i < pos && (tmp->length > 0); i++) { pCur = pCur->next; } //若头部删除时候 pCur依然指向头结点 if (pCur == ((CircleListNode *)tmp)) { //h获取最后一个元素 last = CircleList_Get(tmp,tmp->length-1); } //4 缓存删除元素 DeletNode = pCur->next; //5 连接 删除结点操作 pCur->next = DeletNode->next;//1 //6 链表长度-- tmp->length--; //7 判断last是否为空 if (last!=NULL) { last->next = DeletNode->next;//2 } //8 若删除元素为游标所指元素 需要后移 if (tmp->slider == DeletNode) { tmp->slider = DeletNode->next; } //9 若删除元素后链表长度为0 if (tmp->length == 0) { tmp->header.next = NULL; tmp->slider = NULL; } return DeletNode; } //add //根据结点 直接指定删除链表中的某个数据元素 CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node) { //1 缓存下来 进行操作 TCircleList *tmp = (TCircleList *)list; //辅助指针 用来遍历当前指针位置 CircleListNode *pCur = NULL; //辅助指针 用来缓存删除元素 CircleListNode *DeletNode = NULL; if (NULL == list || 0 == node || 0 == tmp->length) { printf("func err CircleList_DeleteNode\n"); return NULL; } //2 当前指针 初始化 指向 头结点 pCur = &(tmp->header); //3 搜索要获得的结点 int i; for ( i = 0; i < tmp->length; i++) { if (pCur->next == node)//根据删除结点搜索到要删除位置 { DeletNode = pCur->next;//缓存删除元素 break;//这里搜索到要删除的结点,结束循环,否则会报错 } pCur = pCur->next; } //4 根据pos位置删除元素 if (DeletNode != NULL) { CircleList_Delete(tmp,i); } return DeletNode; } //将游标重置指向链表中的第一个数据元素 CircleListNode* CircleList_SliderReset(CircleList* list) { //1 缓存下来 进行操作 TCircleList *tmp = (TCircleList *)list; //辅助指针 用来缓存重置游标位置 CircleListNode *tmpReset = NULL; if (NULL == list) { printf("func err CircleList_Reset\n"); return NULL; } if (tmp!=NULL) { tmp->slider = tmp->header.next;//重置指向第一个数据元素 tmpReset = tmp->slider;//缓存游标位置 } return tmpReset; } //获取当前游标指向的数据元素 CircleListNode* CircleList_SliderCurrent(CircleList* list) { //1 缓存下来 进行操作 TCircleList *tmp = (TCircleList *)list; //辅助指针 用来缓存当前游标位置 CircleListNode *tmpCur = NULL; if (NULL == list) { printf("func err CircleList_Current\n"); return NULL; } if (tmp!=NULL) { tmpCur = tmp->slider;//缓存当前游标位置 } return tmpCur; } //将游标移动指向到链表中的下一个数据元素 CircleListNode* CircleList_SliderNext(CircleList* list) { //1 缓存下来 进行操作 TCircleList *tmp = (TCircleList *)list; //辅助指针 用来缓存游标位置 CircleListNode *tmpNext = NULL; if (NULL == list) { printf("func err CircleList_Next\n"); return NULL; } if (tmp != NULL) { tmpNext = tmp->slider;//缓存当前游标位置 tmp->slider = tmpNext->next;//将游标下移 } return tmpNext; }
//循环链表解决约瑟夫问题实现 //text.c #include <stdlib.h> #include <string.h> #include <stdio.h> #include "CircleList.h"//c里面.h和.cpp没有差别 但是c++里如果模块化编程,两个头文件都必须包含进来 //业务结点 typedef struct _tag_Teacher { CircleListNode node;//包含指针域节点 //下面是业务域 int age; }Teacher; int main() { int ret = 0; CircleList *Cirtmp = NULL; Teacher t1, t2, t3, t4, t5, t6, t7, t8; t1.age = 1; t2.age = 2; t3.age = 3; t4.age = 4; t5.age = 5; t6.age = 6; t7.age = 7; t8.age = 8; //1 构造空的循环链表 Cirtmp = CircleList_Create(); if (NULL == Cirtmp) { ret = -1; printf("func err CircleList_Create:%d\n",ret); return ret; } //2 循环链表的算法 和具体的业务结点 分离 //建立约瑟夫模型 尾插法 //int CircleList_Insert(CircleList* list, CircleListNode* node, int pos) ret = CircleList_Insert(Cirtmp, (CircleListNode *)(&t1), CircleList_Length(Cirtmp)); if (ret!=0) { ret = -2; printf("func err CircleList_Insert:%d\n", ret); return ret; } ret = CircleList_Insert(Cirtmp, (CircleListNode *)(&t2), CircleList_Length(Cirtmp)); ret = CircleList_Insert(Cirtmp, (CircleListNode *)(&t3), CircleList_Length(Cirtmp)); ret = CircleList_Insert(Cirtmp, (CircleListNode *)(&t4), CircleList_Length(Cirtmp)); ret = CircleList_Insert(Cirtmp, (CircleListNode *)(&t5), CircleList_Length(Cirtmp)); ret = CircleList_Insert(Cirtmp, (CircleListNode *)(&t6), CircleList_Length(Cirtmp)); ret = CircleList_Insert(Cirtmp, (CircleListNode *)(&t7), CircleList_Length(Cirtmp)); ret = CircleList_Insert(Cirtmp, (CircleListNode *)(&t8), CircleList_Length(Cirtmp)); //3 遍历循环链表 核实构造约瑟夫模型成功 for (int i = 0; i < 2 * CircleList_Length(Cirtmp); i++) { ////获取一个循环链表list中pos位置处的元素 //Teacher *tmp = (Teacher *)CircleList_Get(Cirtmp, i); //if (NULL == tmp) //{ // ret = -3; // printf("func err CircleList_Get():%d\n", ret); // return ret; //} //printf("%d\t", tmp->age); //通过获取游标所指元素 然后游标下移 遍历 Teacher *tmp = (Teacher *)CircleList_SliderNext(Cirtmp); printf("%d\t", tmp->age); } printf("\n================================我是分界线===============================\n"); //重置游标 CircleList_SliderReset(Cirtmp); while (CircleList_Length(Cirtmp) > 0) { Teacher *tmp = NULL; for (int i = 1; i < 3; i++)//所以这里只要下移两次就好 { //游标下移 CircleList_SliderNext(Cirtmp); } //删除 当前游标所指元素 tmp = (Teacher *)CircleList_SliderCurrent(Cirtmp); printf("delete node:%d\t", tmp->age); CircleList_DeleteNode(Cirtmp,tmp);//删除结点 因为此API调用:若删除元素为游标所指元素 需要后移 } CircleList_Destroy(Cirtmp); system("pause"); return 0; }