约瑟夫环

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;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值