Description
编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个仍开始顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他的顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。请设计一个程序输出出列顺序。
提示:存储结构采用不带头结点的循环单链表,结点结构如下:
typedef struct Node
{ int ID;
int password;
struct Node *next;
}LNode,*LinkList;
要求:
(1)编写建立循环单链表的函数,依次输入每个人的ID和password建立不带头结点的循环单链表。
(2)编写函数,按照规则依次删除相应的元素。
(3)main()函数调用(1)和(2)中的函数,输出约瑟夫序列。
注意:m=1 时需要特殊处理。
Input
输入n
输入m
第1行为n
第2行为m
接下来每行表示每个人的ID和password
Output
依次输出出列者的ID
每输出一个人的ID换行。
Sample Input
8 4 1 3 2 1 3 9 4 2 5 4 6 7 7 4 8 6
Sample Output
4 6 7 3 5 8 2 1
HINT
注意:处理m=1的特殊情况。
输出最后一个人的ID后,也要换行。
/*约瑟夫环*/
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode{ //定义循环链表
int id;
int password;
struct LNode * next;
}LNode,*LinkList;
LinkList CreatList(LinkList head,int n)
{
int i;
LinkList p,q;
head = (LinkList)malloc(sizeof(LNode));
q = head;
scanf("%d %d",&q->id,&q->password);
for(i = 2;i<=n;i++)
{
p = (LinkList)malloc(sizeof(LNode));
scanf("%d %d",&p->id,&p->password);
q->next = p;
q = p;
}
p->next =head;
return head;
}
/*
void Display(LNode *pHeader)
{
LNode *pCurNode;
pCurNode=pHeader;
printf("%d ",pCurNode->password);
while(pCurNode->next!=pHeader)
{
pCurNode = pCurNode->next;
printf("%d ",pCurNode->password);
}
}*/
void Joseph(LinkList head,int k)
{
LinkList p,q;
int m,i;
p = head;
m =k;
/*
for(i = 1;i<k;i++)
{
p = p->next;
}*/
// q = p;
while(p->next!=p)
{
for(i=1;i<m;i++)
{
q=p;
p = p->next;
}
m = p->password;
printf("%d\n",p->id);
q->next = p->next;
free(p);
p = q->next;
}
printf("%d\n",p->id);
free(p);
}
int main()
{
int k,n;
LinkList L,head;
L = NULL;
scanf("%d",&n);
scanf("%d",&k);
head = CreatList(L,n);
//Display(head);
Joseph(head,k);
return 0;
}