[C & C++]利用循环链表解决约瑟夫环问题

本文介绍了如何利用循环链表解决约瑟夫环问题,详细讲解了问题背景、循环链表的创建以及核心解法。通过C和C++的代码实现,展示如何在循环链表中找到报数出局的节点并删除,最终得出解决方案。
摘要由CSDN通过智能技术生成

约瑟夫环问题重述 Problem Details

问题源于一个故事,讲述者据传为著名犹太历史学家Josephus。

罗马人占领乔塔帕特,39个犹太人外加Josephus和他的朋友共计41人躲进一个洞窟,为了躲避敌人的抓捕,决定集体自杀。自杀的规则是所有人围成一个圆圈,确定一个数字从第一个人开始报数,报到数的人自杀,从下一个人开始继续。然而Josephus和朋友反对,于是假装同意。通过将自己和朋友安排在第16和31的位置,避免了死亡的遭遇。

以上故事衍生成了一个经典的数学问题。法国数学家在《数目的游戏问题》提出了类似的问题。
综合各种形式,给出一种最常见的题目形式:

n个人围成一圈,从第一个人开始报数,第m个出局,游戏从下一个人继续,直到最后一人存活,游戏结束。试问每个人的出局顺序。

分析 Analysis

本题具有很多种解法,排除各种编程语言的差异,解法之间的主要区别是选用的数据结构不同。因此,本题分析的入手点即应当选择什么数据结构较优(或者说更顺手更易于理解)

本题可以采用的数据结构非常多,见诸于网络的有数组法循环队列法循环链表法等等,利用递归思想10行之内解决问题的大神也不少见。在这么多的方法中,分析题目可以很容易发现,所有的“人”,也就是各个数据单元,围成了“一圈”,进行循环报数。由此,关键词获得,循环首尾相接,很容易想到“循环队列”或者“循环链表”。循环链表与循环队列实质上是一种数据结构。这里我们尝试选用循环链表解决问题。

那么使用循环链表是否合适呢?
首先,相对于其它数据结构,其本来形式更直观地对应了题目的实际形象;
其次,循环链表可以很容易地构成“循环”;
最后,循环链表进行删除操作相对容易,更方便将其中一个结点删除而不破坏整个数据结构。
综上,使用循环链表是合适的。

创建循环链表 Create a Circular List

C

首先建立一个结点 node,同时因为本题对象只有 Josephus 环中的人,因此直接定义一个结点类型 person:

typedef struct node
{
   
	int number;
	struct node *next;
}person;

接下来就利用上面定义的 person 结点创建循环链表结构 CirList,int型变量n用于接收链表的结点数:

person *CirList( int n )
{
   
	person *head = (person *)malloc(sizeof(person));//Create the head node
	head->number = 1;	//The 1st person is 1.
	head->next = head;	//Make head connects to itself making it the Circular List.
	
	person *BodyCreator = head; 	//Set a pointer to help make the body
	int i;				//Every i is a person node coming after the head node
	for (i = 2; i <= n; i++)
	{
   
		person *body = (person*)malloc(sizeof(person));
		body->number = i;	//Keypoint~Cause its the person after No.1 so he starts from 2
		body->next = NULL;

		body = BodyCreator->next;	//Attach the body to the CirList
		BodyCreator = BodyCreator
  • 8
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值