1、编号为1到N的N个人围着圆桌按序号坐着,从编号为1的人开始循环数数,数到M时对应的人离开座位,求最后剩下的那个人的编号?
代码如下:
#include "stdafx.h"
#include <string>
#include <iostream.h>
//编号为1到N的N个人围着圆桌按序号坐着,从编号为1的人开始循环数数,数到M时对应的人离开座位,求最后剩下的那个人的编号
#define M 4
#define N 10
//定义数据结构
typedef struct Josephus
{
int index;
Josephus *next;
}*PJosephus;
PJosephus PJ; //Josephus环头节点
//创建Josephus环--循环链表
void CreateJosephus()
{
PJ=(PJosephus)malloc(sizeof(Josephus));
PJ->index=1;
PJ->next=PJ;
PJosephus pTemp=PJ,pNew;
for (int i=2;i<=N;i++)
{
pNew=(PJosephus)malloc(sizeof(Josephus));
pNew->index=i;
pNew->next=PJ;
pTemp->next=pNew;
pTemp=pNew;
}
}
//Josephus环的长度
int JosephusLen()
{
int len=0;
PJosephus pHead=PJ;
do
{
len++;
pHead=pHead->next;
} while (pHead!=PJ);
return len;
}
//开始游戏
void StartGame()
{
PJosephus p=PJ,pTemp,q=PJ;
while(1!=JosephusLen()) //循环终止条件:Josephus环长度为1
{
if (M==1) //步长M为1时,特殊处理,因为每次删除的是循环链表的头节点
{
PJ=PJ->next;
for (int i=0;i<JosephusLen()-1;i++)
{
q=q->next;
}
q->next=PJ; //最后一个节点需要更新,指向头结点(注意循环链表的头节点删除的特殊性)
q=PJ;
free(p);
p=PJ; //更新删除节点的下一个节点p
}
else
{
for (int i=1;i<M;i++)
{
pTemp=p; //pTemp指向待删节点的前一个节点
p=p->next;
}
pTemp->next=p->next;
if (p->index==PJ->index) //当删除的是头结点时,更新头结点
{
PJ=p->next;
}
free(p);
p=pTemp->next; //更新删除节点的下一个节点
}
}
}
int main(int argc, char* argv[])
{
CreateJosephus();
StartGame();
cout<<PJ->index<<endl;
return 0;
}