编号为 1,2,… ,n 的n个人按顺时针方向围坐一圈,每人均持有一个密码(正整数)。游戏开始由系统随机产生一个正整数m(1~10之间),同时随机产生一个起始位置s(正整数),从第s人开始按顺时针方向开始顺序报数,报到m时停止报数。报m的人出列,获取出列人的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。要求做到:
1)出列结束时可以一次性完整输出所有出列人的信息。
2)出列结束时可以一次性逆序输出出列人的信息。
3)在出列过程中随时可以查询某人是否已经出列。
4)在出列过程中随时可以查询已经出列的人数。
(各功能用菜单方式实现。)
#include<stdio.h>
#include<stdlib.h>
#define ElemType int
#define OK 0
#define OVERFLOW 0
#define ERROR 0
typedef struct LNode{
int data;
int password;
struct LNode *next;
}LNode, *LinkList;
//创建约瑟夫环
LinkList* CreateList_L(LinkList *L,int z)//返回LinkList类型struct LNode**可不可以去掉一个星??
{
int key,i;
LinkList p,q;
(*L)=(LinkList)malloc(sizeof(LNode)); //L指向首地址
q = (*L);
q->next = NULL;
for(i=1;i<=z;i++)
{
p=(LinkList)malloc(sizeof(LNode));
q->next = p;
p->next = NULL;//必须保持空
p->data = i;
printf("输入第%d个人的密码:",i);
scanf("%d",&key);
p->password = key;
q = p; //????????
}
*L = (*L)->next;///是删除L?L是否改变???????
p->next = *L;//实现循环
//p->next = (*L)->next;
return L;//返回首地址
}
//对单循环链表进行操作
Operate(LinkList L,int h,int n){
int i = 1,j;
LinkList J;
for(i =1;i<n;i++)
{
for(j =1;j<h;j++)
{
J=L;
L=L->next;
}
J->next = L->next;
printf("第%d个出列的人的编号是: %d 密码是:%d\n",i,L->data,L->password);
h = L->password;
L = L->next;
}
i = L->password;
j = L->data;
printf("最后一个出局的人的编号是:%d 密码是:%d/n",j,i);
}
/*status ListDelete_L(Linklist &L, int i, ElemType &e){
//在带头结点的单循环链表L中,删除第i个元素,并由e返回其值
p = L; j =0;
// int E[100]= 0;
while( j<i-1){//寻找第i个结点,并令p指向其前驱
p = p->next;
if(p->next = L->next)//最后有循环回来第一个人
++j;
}
q = p->next;
p->next = q->next; //删除i点
e = q->data;
L->next = p->next; //同时将下一个即p->next赋为头结点
free(q);
return 0 ;
}
*/
void main()
{
LinkList I,*k;
int n,m;
printf("输入参加人数n");
scanf("%d",&n);
printf("起始报数的上限值m");
scanf("%d",&m);
k = CreateList_L(&I,n);//返回值L的首地址、
I = *k;//欲把操作的首地址再指向约瑟夫环的首地址
printf("输出结果为:\n");
Operate(I,m,n);
}