/*Josephus 问题 N个人从1到N编号,围坐成一个圆圈。从1号开始传递一个热土豆。经过M次传递后拿着热土豆的人被清除离座,围坐的圆圈缩紧,由坐在被清除的人后面的人拿起热土豆继续进行游戏,最后剩下的人取胜*/
//头文件
#ifndef _Josephus_H
typedef struct Node *PtrToNode;
typedef PtrToNode Position;
typedef PtrToNode List;
Position CreatRingList(int n);
void PrintList(Position phead);
int Winner(Position phead,int n,int m);
#endif
#include <stdio.h>
#include "josephus.h"#include <stdlib.h>
struct Node{
int element;
Position next;
};
// 循环链表
{
int i;
Position head,p,tail;
List L;
L=(List)malloc(sizeof(struct Node));
if(L==NULL)
{
printf("error");
return NULL;
}
head=L;
head->element=1;
head->next=head;
tail=head;
for(i=2;i<=n;i++)
{
p=(Position)malloc(sizeof(struct Node));
if(L==NULL)
{
printf("error");
return NULL;
}
p->element=i;
tail->next=p;
p->next=head;
tail=p;
}
return head;
}
void PrintList(Position phead)
{
Position p=phead;
while(p->next!=phead)
{
printf("%d",p->element);
p=p->next;
}
printf("%d",p->element);
}
//返回获胜的序号
{
int i,j;
Position p,q;
p=phead;
//printf("%d",p->element);
if(m==0)
return phead->element;
/*外循环:n个数,最后剩下一个,删除n-1个,即循环n-1次。内循环:每向后m次,删除一项,循环m次。
内循环:p指针为开始位置,p指针向后移动,q记录p的前一项。当移动m次时,开始删除操作。
删除操作:q的下一项为p-next,p所指项被删除,p重新赋值为删除项的后一项,即q->next。
重新开始删除操作。直到剩下一个为止*/
for(i=1;i<n;i++)
{
for(j=1;j<=m;j++)
{
q=p;
p=p->next;
}
q->next=p->next;
//printf("%d",p->element);
free(p);
p=q->next;
}
return p->element;
}
main()
{
int winnernum;
Position phead;
phead=CreatRingList(5);
//PrintList(phead);
winnernum=Winner(phead,5,3);
printf("the winner is %d",winnernum);
}