1 约瑟夫环问题描述:
约瑟夫环问题是循环链表的经典应用:具体描述如下:n 个人围成一个圆圈,首先第 1 个人从 1 开始一个人一个人顺时针报数,报到第 m 个人,令其出列。然后再从下一 个人开始从 1 顺时针报数,报到第 m 个人,再令其出列,…,如此下去,求出列顺序。
2 约瑟夫环问题求解
利用循环链表,根据游标在循环链表中的移动,依次输出元素的值,直到循环链表为空:这里借助上一篇的循环链表。这里直接给出约瑟夫问题的求解过程:
其中CircleList.h和CircleList.cpp在上一篇文章中给出
#include"CircleList.h"
#include<stdio.h>
#include<stdlib.h>
struct Value
{
CircleListNode circlenode;//包含指针域节点
int v;
};
//约瑟夫环问题
int main()
{
int i = 0;
CircleList * list = CircleList_Create();//创建链表
struct Value v1, v2, v3, v4, v5, v6, v7, v8;
v1.v = 1; v2.v = 2; v3.v = 3; v4.v = 4;
v5.v = 5; v6.v = 6; v7.v = 7; v8.v = 8;
CircleList_Insert(list, (CircleListNode *)&v1, CircleList_Length(list));
CircleList_Insert(list, (CircleListNode *)&v2, CircleList_Length(list));
CircleList_Insert(list, (CircleListNode *)&v3, CircleList_Length(list));
CircleList_Insert(list, (CircleListNode *)&v4, CircleList_Length(list));
CircleList_Insert(list, (CircleListNode *)&v5, CircleList_Length(list));
CircleList_Insert(list, (CircleListNode *)&v6, CircleList_Length(list));
CircleList_Insert(list, (CircleListNode *)&v7, CircleList_Length(list));
CircleList_Insert(list, (CircleListNode *)&v8, CircleList_Length(list));
for (i = 0; i < CircleList_Length(list); i++)
{
//获取游标所指元素,然后游标下移
struct Value* pv = (struct Value *)CircleList_Next(list);
printf("%d ", pv->v);
}
printf("\n\n");
//重置游标
CircleList_Reset(list);
while (CircleList_Length(list) > 0)
{
struct Value *pv = NULL;
for (i = 1; i < 3; i++)
{
CircleList_Next(list);
}
pv = (struct Value *)CircleList_Current(list);
printf("%d ", pv->v);
CircleList_DeleteNode(list, (CircleListNode *)pv);//根据节点的值进行节点元素删除
}
printf("\n\n");
CircleList_Destory(list);
return 0;
}
运行结果如下: