约瑟夫(Joseph)问题的一种描述是:编号为1,2,.....,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有的人都出列为止。试设计一个程序求出列顺序。
#include <stdio.h>
#include <malloc.h>
typedef struct Listnode
{
int num;
int key;
struct Listnode *next;
}Listnode,*pListnode;
int create_list(pListnode *p, int i, int key)
{
pListnode q = NULL;
if(*p == NULL)
{
q = (pListnode)malloc(sizeof(Listnode));
if(!q)
{
printf("分配内存失败!\n");
return -1;
}
q->num = i;
q->key = key;
q->next = NULL;
*p = q;
}
else
{
q = (pListnode)malloc(sizeof(Listnode));
if(!q)
{
printf("分配内存失败!\n");
return -1;
}
q->num = i;
q->key = key;
q->next = NULL;
(*p)->next = q;
*p = q;
}
return 0;
}
void ysfhuan(pListnode head, int n, int m)
{
int i;
pListnode p = NULL, q = NULL;
p = q = head;
while(q->next != head)
q = q->next;
while(n > 0)
{
for(i=1;i<m;i++)//注意没有等号
{
p = p->next;
q = q->next;
}
q->next = p->next;
printf("%d\t",p->num);
m = p->key;
free(p);
p = q->next;
n--;
}
p = NULL;
}
int main()
{
pListnode head = NULL, p = NULL;
int n,m,key,i;
printf("请输入人数:\n");
scanf("%d",&n);
printf("请输入初始密码:\n");
scanf("%d",&m);
printf("请依次输入大家手中的密码:\n");
for(i=1;i<=n;i++)
{
scanf("%d",&key);
if(create_list(&p,i,key) == -1)
return -1;
if(i == 1)
head = p;
}
p->next = head;
printf("出环顺序如下:\n");
ysfhuan(head,n,m);
printf("\n");
return 0;
}