循环单链表法实现Josephus问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
向量法求解Josephus问题
智能一班林潇 2220101468
一.实验题目描述
Josephus问题可描述如下:
设有n个人围成一个环,现从第s个人开始报数,数到第m的人出列,然后从出列的下一个人从新开始报数,数到第m的人又出列,如此重复,直至所有人均出列为止。求这些人出列的顺序。
二.实验目的
熟练掌握线性表的链表实现基本操作。
三.实现功能
以循环单链表为存储结构,求解Josephus问题。
四.算法步骤
编写一个独立的函数模块求解Josephus问题,该函数仅通过参数与外界进行数据交换,不使用其它非局部变量,实现方案应具有良好的健壮性。另编写一个主函数作为驱动,在主函数中处理数据的输入与输出。
五.程序结构描述
程序主要包括一个驱动功能的主函数,包括要排列数组元素的输入,开始报数的位置,所报数字的输入。还有一个独立函数模块来实现Josephus问题,主函数通过调用该函数来实现元素的出列,并将出列元素按顺序重新存入数组,并将出列元素按顺序输出。
六.程序代码
#define N 10
#include
#include
typedef struct LNode{//建立节点类型
int message;
struct LNode *next;
}LNode,*LinkList;
void Josephus(LinkList L,int s,int m,int n,int e,int a[]);
void main(){
int i,s,m,e;
int a[10];
printf("请输入Josephus环的元素");
//输入组成Josephus环的元素
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("请输入开始报数位置及所报数字");
//输入开始报数位置及所报数字
scanf("%d %d",&s,&m);
LinkList L;//建立单循环连的头结点
L=(LinkList)malloc(sizeof(LNode));
L->message=a[0];
L->next=NULL;
Josephus(L,s,m,N,e,a);
}
void Josephus(LinkList L,int s,int m,int n,int e,int a[]){ LinkList p,q;
int i,j;
//将组成Josephus环的元素储存到单链中
for(i=n-1;i>0;i--){
p=(LinkList)malloc(sizeof(LNode));
p->message=a[i];
p->next=L->next;
L->next=p;
}
LinkList H;
H=L;
for(i=0;i H=H->next; H->next=L;//尾部节点的指针指向头结点 p=L; for(i=1;i p=p->next;//找到开始报数位置 i=1; //利用循环将元素输出 while(p->next!=p->next->next){ for(j=1;j p=p->next; q=p->next; p->next=q->next; e=q->message; free(q);//释放被输出元素的节点 printf("\n第%d 个出列的元素为%d\n",i,e); p=p->next; i++; } printf("\n第%d 个出列的元素为%d\n",10,p->message); } 七.测试数组及结果 测试数组为一个长度为10的整形数组,存储元素为1-10是个整数。开始报数位置为数组的第二个元素,所报数字为3。测试结果截屏如下: 八.实验总结与体验 本次实验比较成功,通过解决Josephus问题学会了链表存储结构的使用。并对单链表,循环链表存储数据有了较深的体会。