循环链表的存储设计与实现以及利用循环链表解决约瑟夫问题实现(C语言版本)

循环链表插入元素的思想图:

尾插法时候,有点不一样:需要处理



循环链表
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;
}


猜你喜欢

转载自blog.csdn.net/weixin_40807247/article/details/80333746