用顺序表解决约瑟夫问题

编号为 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);

}