约瑟夫问题(环形链表) C语言

**有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的人退出圈子,问最后最后留下的是原来第几号的那位. **

约瑟夫问题
基于环形链表实现

这里要注意的是
代码中的变量k用来记录现在报的数
当k为2时,则说明下一个人报数3,释放下一个人的空间(把下一个人踢出队列),若等到k为3再释放,还要记录上一个人的next的指向,指向k为3的next,所以在k=2时就处理,会比较方便

编号从一开始
输入总人数
输出最后留下的那个人的编号
具体解释已在代码注释中给出,若有不懂,可以评论区留言或者私信,我会尽快回复的。

#include <stdio.h>
#include <stdlib.h>
typedef struct node  //定义链表
{
	int number;   //存储每个人的编号,从1开始
	struct node* next;
}Link,*PLink;
int yue(int n);     //判断约瑟夫问题最后的答案
int main()
{
	int n;
	printf("请输入人数:");
	scanf("%d", &n);
	printf("最后留下的人是:%d\n", yue(n));

	return 0;
}
int yue(int n)
{
	PLink head = NULL;   //头指针
	PLink p = NULL, q = NULL;   //建链表辅助指针
	for (int i = 0; i < n; i++)
	{
		q = (PLink)malloc(sizeof(Link));  //申请新的空间
		q->number = i + 1;
		q->next = NULL;
		if (head == NULL)
			head = q;   //头指针为空,则给头指针指向申请的空间
		else
			p->next = q;
		p = q;   //保留此次循环申请的空间
	}
	p->next = head; //结尾next指向头部,组成环形链表
	int k = 0;
	//int j = 7;
	while (1)
	{
		if (head->next == head)   //当环形链表只剩一个元素时,结束循环
			break;	
		k++;
		if (k == 2)    //当k为2时,则说明下一个人报数3,释放下一个人的空间,若等到k为3再释放,情况会较麻烦
		{
			printf("%d\n", head->next->number);  //打印出出列的人
			q = head->next; 
			head->next = head->next->next;  //next直接指向下下个元素
			free(q);   //释放下一个元素
			k = 0;
		}
		head = head->next;
	}
	return head->number;   //返回最后剩下的那个人的编号
}

运行截图:
在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值