问题描述
约瑟夫问题 (本题要求用循环链表实现)
约瑟夫问题是一个经典的问题。已知n个人(不妨分别以编号1,2,3,…,n 代表 )围坐在一张圆桌周围,从编号为 k 的人开始,从1开始顺时针报数1, 2, 3, …,顺时针数到m 的那个人,出列并输出。然后从出列的下一个人开始,从1开始继续顺时针报数,数到m的那个人,出列并输出,…依此重复下去,直到圆桌周围的人全部出列。
输入
输入:n, k, m
输出
输出:按照出列的顺序依次输出出列人的编号,编号中间相隔一个空格,每10个编号为一行。
非法的输入输出
a) 输入:n、k、m任一个小于1
输出:n,m,k must bigger than 0.
b)输入:k>n
输出:k should not bigger than n.
例:
输入:9,3,2
输出:4 6 8 1 3 7 2 9 5
样例
输入(1)
9,3,2
输出(1)
4 6 8 1 3 7 2 9 5
输入(2)
10,12,3
输出(2)
k should not bigger than n.
代码
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n,k,m;
scanf("%d,%d,%d",&n,&k,&m);
if (n<1||k<1||m<1)
{
printf("n,m,k must bigger than 0.\n");
return 0;
}//特殊情况判断
if (k>n)
{
printf("k should not bigger than n.\n");
return 0;
}//特殊情况判断
else
{
struct node
{
int id;
struct node *next;
};
struct node *head,*p,*q,*tmp;
head=(struct node*)malloc(sizeof(struct node));
//为头节点申请存储空间
head->id=-1;
head->next=head;
//构建循环链表
for (int i=n;i>=1;i--)
{
tmp=(struct node*)malloc(sizeof(struct node));
tmp->next=head->next;
head->next=tmp;
tmp->id=i;
if (tmp->id==k)
{
p=tmp;
}
}
//初始化队伍
//并定位到第k个人的位置
while(tmp->next!=head)
{
tmp=tmp->next;
}
tmp->next=head->next;
//将头节点移出队伍,构建循环链表
int count=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<m;j++)
{
p=p->next;
}
count++;
if((count%10)==0||i==n)
{
printf("%d\n",p->id);
}
else
{
printf("%d ",p->id);
}
p->id=p->next->id;
q=p->next;
p->next=q->next;
free(q);
}
free(head);
//释放头结点的空间
}
return 0;
}