环形链表的约瑟夫问题

目录

1.定义节点

2.创建节点

3.创建不带头循环单链表

4.约瑟夫函数实现

5.总代码


描述:

编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。

下一个人继续从 1 开始报数。

n-1 轮结束以后,只剩下一个人,问最后留下的这个人编号是多少?

数据范围:1<=n,m<=10000

1.定义节点

objectivec 复制代码
typedef struct ListNode
{
	int val;
	struct ListNode* next;
}ListNode;

2.创建节点

objectivec 复制代码
//创建节点
ListNode* BuyNode(int x)
{
	ListNode* node = (ListNode*)malloc(sizeof(ListNode));
	if (node == NULL)
	{
		perror("node malloc");
		exit(1);
	}
	node->val = x;
	node->next = NULL;
	return node;
}

3.创建不带头循环单链表

objectivec 复制代码
//创建不带头循环单链表
ListNode* CreateCircle(int n)
{
	ListNode* head = BuyNode(1);
	ListNode* ptail = head;
	int i = 0;
	for (i = 2; i <= n; i++)
	{
		ptail->next = BuyNode(i);
		ptail = ptail->next;
	}
	ptail->next = head;
	return ptail;//m为1时,需要知道尾节点的地址
}

4.约瑟夫函数实现

objectivec 复制代码
int ysf(int n, int m)
{
	ListNode* prev = CreateCircle(n);//指向尾节点
	ListNode* pcur = prev->next;//指向第一个节点
	int count = 1;//pcur已经指向第一个节点
	while (pcur->next != pcur)
	{
		if (count != m)
		{
			prev = prev->next;
			pcur = pcur->next;
			count++;
		}
		else
		{
			prev->next = pcur->next;
			free(pcur);
			pcur = prev->next;
			count = 1;
		}
	}
	int ret = pcur->val;
	free(pcur);
	pcur = prev = NULL;
	return ret;
}

最后四行代码是将pcur所指向的地址空间释放,先存pcur->val的值,再释放,不然找不到了

5.总代码

objectivec 复制代码
#include <stdio.h>
#include <stdlib.h>

typedef struct ListNode
{
	int val;
	struct ListNode* next;
}ListNode;
//创建节点
ListNode* BuyNode(int x)
{
	ListNode* node = (ListNode*)malloc(sizeof(ListNode));
	if (node == NULL)
	{
		perror("node malloc");
		exit(1);
	}
	node->val = x;
	node->next = NULL;
	return node;
}
//创建不带头循环单链表
ListNode* CreateCircle(int n)
{
	ListNode* head = BuyNode(1);
	ListNode* ptail = head;
	int i = 0;
	for (i = 2; i <= n; i++)
	{
		ptail->next = BuyNode(i);
		ptail = ptail->next;
	}
	ptail->next = head;
	return ptail;//m为1时,需要知道尾节点的地址
}

int ysf(int n, int m)
{
	ListNode* prev = CreateCircle(n);//指向尾节点
	ListNode* pcur = prev->next;//指向第一个节点
	int count = 1;//pcur已经指向第一个节点
	while (pcur->next != pcur)
	{
		if (count != m)
		{
			prev = prev->next;
			pcur = pcur->next;
			count++;
		}
		else
		{
			prev->next = pcur->next;
			free(pcur);
			pcur = prev->next;
			count = 1;
		}
	}
	int ret = pcur->val;
	free(pcur);
	pcur = prev = NULL;
	return ret;
}
int main()
{
	int m, n;
	scanf("%d,%d", &m, &n);
	printf("%d", ysf(m, n));
	return 0;
}
相关推荐
玖玥拾13 小时前
C++ 数据结构 八大基础排序算法专题
数据结构·c++·算法·排序算法
Tim_1013 小时前
【C++】017、new/delete与malloc/free的区别
java·数据结构·算法
从零开始的代码生活_14 小时前
C++ list 原理与实践:双向链表、迭代器与简化实现
开发语言·c++·后端·学习·算法·链表·list
岑梓铭16 小时前
《考研408数据结构》第六章(6.3 图的遍历)复习笔记
数据结构·笔记·考研··拓扑排序·408
noipp19 小时前
推荐题目:洛谷 P13554 【MX-X15-T1】奶龙龙
c语言·数据结构·c++·算法·编程·洛谷
AI科技星20 小时前
《全域数学·工程应用大典》113–200讲完整总目录
数据结构·人工智能·算法·机器学习·线性回归·乖乖数学·全域数学
米尔的可达鸭1 天前
深入操作系统 Socket 底层:EPOLLOUT 可写事件管理 + 非阻塞异步
开发语言·网络·数据结构·经验分享·websocket·网络协议
Irissgwe1 天前
算法之二分查找
数据结构·c++·算法·二分查找
小蒋学算法1 天前
算法-滑动窗口最大值
数据结构·算法
youtootech1 天前
HarmonyOS《柚兔学伴》项目实战09-待办列表 UI——List+ForEach+滑动删除
数据结构·ui·华为·list·harmonyos