需求分析
一群小孩编号为1,2,…,n(n>0)围成一圈,有一个刚出锅的山芋在他们之间传递。假设刚开始由1号拿着山芋,然后依次计数把山芋交给下一个小孩,当数到某个特定的k时,拿着山芋的小孩退出游戏,然后从下一个小孩重新开始计数,如此不断,最后剩下的那个孩子就是幸运者。要求设计一个程序模拟次过程,并给出不同的n,k组合下那个幸运者是谁?
1、 输入的形式和输入值的范围:演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入相应的数据,每个人的序号由程序自动分配。以int型输入,范围在-2147483648~2147483648;
2、 输出的形式:int型;
3、 程序所能达到的功能:构造链表;输入数据;执行报数;储存出列人的序号,删除出列人的信息以及把指向出列人的指针移到出列人的下一个人,然后重新开始执行报数;直到最后一个人报数完毕,程序结束。
4、 测试数据:n=9,9个人的序号分别为:1,2,3,4,5,6,7,8,9。然后b=1,从第一个开始报数。k=5,则确定输出的序列为:5,1,7,4,3,6,9,2,8。
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;//指针域
int size;//循环链表的长度
} node,*linklist; //linklist为定义的指针结构体变量
void create_list_tail(linklist *l)//尾插法建立循环链表
{
int a[100];
int i,j,x;
linklist p,r,t;
j=9;
(*l)=(node*)malloc(sizeof(node));
(*l)->next=NULL;
(*l)->size=j;
t=(*l);
x=1;
for(i=0; i<j; i++)
{
p=(node*)malloc(sizeof(node));
p->data=x;
t->next=p;
t=p;//每新建一个结点在结束时都为最后一个结点,下一个节点在这个结点后面插入
x++;
}
t->next=NULL;
r=(*l)->next;
while(r->next!=NULL)
{
r=r->next;
}
r->next=(*l)->next;
}
void realise(linklist *l)//约瑟夫环的实现并打印输出
{
int i,j,k,x;
int a[100];
linklist p,r,t;
p=(*l)->next;
k=(*l)->size;
for(i=0; i<k; i++)
{
for(j=0; j<3; j++)
{
p=p->next;
}
a[i]=p->next->data;
t=p->next;
p->next=t->next;//每次找到这个结点并把这个结点删除
free(t);
p=p->next;//从下一个节点重新开始循环
}
for(i=0; i<9; i++)
{
printf("%d\n",a[i]);
}
}
int main()
{
linklist a;
create_list_tail(&a);
realise(&a);
return 0;
}
这是根据题目要求做出的,也可以修改参数使他适应更大的范围