用链表知识解决约瑟夫环

什么是约瑟夫环

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知 n 个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。 从编号为 k 的人开始报数,数到 m 的那个人出圈;他的下一个人又从 1 开始报数,数到 m 的那个人又出圈;依此规律重复下去,直到剩余最后一个胜利者。 例如:有10个人围成一圈进行此游戏,每个人编号为 1-10 。

怎样用链表知识解决约瑟夫环问题

首先,我们需要创建一个环形链表(必须要环形),每个单结构体里包含一个数据域(date)和一个指针域,数据域用来存放编号。然后我们要定义两个int* 型的变量,设为p,q,因为当报数报到某个数时,那个数就要被删除,在链表中也就是要删除对应的结构体,所以p,q也必须在一前一后的位置,一开始假设p在前并且p=head,q在后,q=head->next,并需要一个变量来计数设为i,i的初始值为1,当i每增加一位,p,q就要按指定的方向移动一位,当i=n(题中设定的数)时,我们就删除q所在的结构体也就是free(q),然后i又从1开始计数,以此类推
如果题中还需要还需要统计被删除的数据的话,那我们就还需要定义一个数组,假设为answer[100],同时还要定义一个用来遍历数组的变量j=0,当i每到达一次n时,就执行answer[j]=q->date,同时j++。
我们就以上面这个问题为例来编写代码,10个人,设定的数字为3

#include<stdio.h>
#include<stdlib.h>
typedef struct Circle{
	int date;
	struct Circle* next;
	}circle;
int main()
{
	int m,n,i,j;
	int answer[100];
	j=0;
	m=10;
	printf("输入设定的数:");
	scanf("%d",&n);
	circle *head,*p,*q,*tail;
	head=(circle *)malloc(sizeof(circle));
	head->next=NULL;
	tail=head;
	for(i=0;i<m;i++)
	{
		p=(circle *)malloc(sizeof(circle));
		p->date=i+1;
		tail->next=p;
		p->next=head->next;
		tail=p;
	}
	q=head->next;
	p=tail;
	i=1;
	while(p!=q)
	{
		if(i==n)
		{
			answer[j]=q->date;
			p->next=q->next;
			free(q);
			i=1;
			q=p->next;
			j++;
		}
		else
		{
			p=q;
			q=q->next;
			i++;
		}
	}
	printf("胜利的数字为%d\n",p->date);
	printf("被删除的数字依次为:");
	for(i=0;i<j;i++)
	{
		printf("%d ",answer[i]);
	}
	return 0;
}

以上就是有关于约瑟夫环问题的解答了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值