【c语言习题】使用链表解决约瑟夫问题

这篇具有很好参考价值的文章主要介绍了【c语言习题】使用链表解决约瑟夫问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c语言系列专栏:c语言之路重点知识整合 🔥
给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ

链表有关知识点:【c语言】链表

题目:

约瑟夫问题

据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后, 39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus和他的朋友并不想遵从。

首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决。

Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个第31个位置,于是逃过了这场死亡游戏。

数组方法:【c语言习题】使用数组解决约瑟夫问题


过程分析:

定义链表节点类型Node,包含两个域:data和指向下一个节点的指针next。

typedef struct node //定义链表 节点
{
	int data;
	struct node* next;
}Node;

定义函数void fun(int n, int m),参数n为总人数,m为报数出局的数字

void fun(int n, int m)  //总共有n个人,报数为m的人出局 

初始化循环链表:

创建头结点head
head->data赋值为1
head->next赋值为NULL

然后用p和q两个指针完成插入操作,让p指向headq表示新插入的节点

	//初始化循环链表
	Node* head = NULL;	//头节点
	head = malloc(sizeof(Node));  
	head->data = 1;       //起始编号
	head->next = NULL;    
	Node* p = head;

	Node* q = NULL;

尾插法创建链表并构造循环链表:

从2开始遍历创建剩下的N-1个结点,每个结点依次插入到链表的尾部,即将p->next=r; q=p;
最后将最后一个节点p的next指针指向头节点head,完成循环链表的构建

for (int i = 2; i <= n; i++)//创建链表的n-1个节点
	{
		q = malloc(sizeof(Node));
		q->data = i;
		q->next = NULL;
		
		p->next = q;//插入节点
		p = q;
	}
	
	p->next = head;   //最后一个节点的next指向头节点
	p = head;  //记录头节点      

找到需要淘汰的节点:

计数器m每次加一,同时移动p指针,当m变成选定的淘汰数字时,
保留p指针位置(即将要淘汰的同学的位置),然后将p指向下一个同学
将淘汰同学输出,并将p指向下一个同学继续报数

while (p->next != p)  //链表中只剩下最后一个节点
	{
		for (int i = 1; i < m; i++)  //报数为m出局 
		{
			q = p;   //通过临时指针保存所对应节点的前一个节点的地址,最终找到需要删除的节点p,并输出节点data
			p = p->next; 
		}
		
		printf("%d ", p->data);
		q->next = p->next;
		p = p->next;  //重置p重新报数
	}

当只有一个节点时,结束淘汰循环

printf("%d\n", p->data);
	printf("存活最后的%d位\n", m-1);
	free(q);
	free(head);
	q = NULL;
	head = NULL;

淘汰过程图解

【c语言习题】使用链表解决约瑟夫问题

完整代码:

#include <stdio.h>
typedef struct node //定义链表 节点
{
	int data;
	struct node* next;
}Node;

void fun(int n, int m)  //总共有n个人,报数字为m的人出局 
{
	//初始化循环链表
	Node* head = NULL;	//头节点
	head = malloc(sizeof(Node));  
	head->data = 1;       //起始编号
	head->next = NULL;    
	Node* p = head;

	Node* q = NULL;
	
	for (int i = 2; i <= n; i++)//创建链表的n-1个节点
	{
		q = malloc(sizeof(Node));
		q->data = i;
		q->next = NULL;
		
		p->next = q;//插入节点
		p = q;
	}
	
	p->next = head;   //最后一个节点的next指向头节点
	p = head;  //记录头节点      

	
	while (p->next != p)  //链表中只剩下最后一个节点
	{
		for (int i = 1; i < m; i++)  //报数为m出局 
		{
			q = p;   //通过临时指针保存所对应节点的前一个节点的地址,最终找到需要删除的节点p,并输出节点data
			p = p->next; 
		}
		
		printf("%d ", p->data);
		q->next = p->next;
		p = p->next;  //重置p重新报数
	}
	printf("%d\n", p->data);
	printf("存活最后的%d位\n", m-1);
	free(q);
	free(head);
	q = NULL;
	head = NULL;
}

int main()
{
	int n, m;
	printf("请输入总人数:");
	scanf_s("%d", &n);
	printf("请输入报数的数字:");
	scanf_s("%d", &m);
	fun(n, m);

	system("pause");
	return 0;
}

结果:

【c语言习题】使用链表解决约瑟夫问题


【c语言习题】使用链表解决约瑟夫问题文章来源地址https://www.toymoban.com/news/detail-473401.html

大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●)

到了这里,关于【c语言习题】使用链表解决约瑟夫问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 力扣环形链表(1)进阶环形链表(2)及环形链表的约瑟夫问题

    为了加深对环形链表的理解和掌握,这两道题是很不错的选择。 这里所说环形链表不是一个圈圈的结构,而是带环链表。 链接:环形链表(1) 注意这里链表的长度 所以要注意链表是否为空 第一种方法,应该是比较容易想到的方法(偷鸡取脚)  遍历链表,将每个节点的

    2024年02月06日
    浏览(23)
  • C语言:约瑟夫环问题详解

    前言 哈喽,宝子们!本期为大家带来一道C语言循环链表的经典算法题(约瑟夫环)。 据说著名历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被人抓到,于是决定了一个自杀方式,41个人

    2024年04月13日
    浏览(21)
  • 约瑟夫环问题解决

    单链表 实现 错例 在使用malloc函数开辟的空间中,不要进行指针的移动, 因为一旦移动之后可能出现申请的空间和释放空间大小的不匹配 循环链表 单独创建 逐节点创建 约瑟夫环问题 实现方式一: 实现方式二: 删除节点并建立新链表 实现

    2024年02月02日
    浏览(28)
  • C语言 | 约瑟夫问题(猴王争夺战)

             约瑟夫问题有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。下面我们将用猴子争大王这一故事以及采用单向循环链表这一方法来进行讲解这一问题。         设编号为1,2,……n得n个猴子围

    2024年02月01日
    浏览(25)
  • 数据结构实验---顺序表的合并---链表的基本操作---重点解析约瑟夫问题

    实验的写法多种多样,但本文并未采用 #define 定义容量的写法,这样写已经是很老旧过时的写法。所有实验主体采用均为动态开辟,后续如果利用 C++ 来写或许会应用更多语法… 本篇展示数据结构的两个实验 其中,重点分析约瑟夫问题 实验中代码的命名风格等均与下方博客

    2024年02月16日
    浏览(49)
  • 数据结构—约瑟夫环问题(C语言版)

    目录 首先什么是约瑟夫环 约瑟夫环实现方式 一、创建结构体变量 二、初始化链表 三、构建循环链表 四、删除链表  五、完整代码及注释讲解 约瑟夫环 是 循环链表 中的一个经典问题;题目描述:n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新

    2024年02月11日
    浏览(31)
  • 循环链表解决约瑟夫环问题

    n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 1开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。 n个人围成一圈,很容易可以想到用循环链表解决问题,用结点代表每个人,节点的数据域存储人的编号

    2024年02月07日
    浏览(31)
  • 4种方法解决约瑟夫环问题

            约瑟夫环问题是大多数编程初学者必须要跨越的一道坎。在第一次见到它的时候,我还是个刚刚学会循环语句的小蒟蒻,而现在的我已经是深陷图论以及各种其他算法的大蒟蒻了(bushi)。可以说,约瑟夫环问题是我从编程基础向编程思维踏出的重要一步。        

    2024年02月12日
    浏览(25)
  • 【数据结构】使用循环链表结构实现约瑟夫环问题

    目录 1.循环链表的定义 2.约瑟夫环问题 3.创建循环链表 4.删除节点操作 5.打印所有节点 6.实现约瑟夫环问题的完整程序代码 🌈嗨!我是Filotimo__🌈。很高兴与大家相识,希望我的博客能对你有所帮助。 💡本文由Filotimo__✍️原创,首发于CSDN📚。 📣如需转载,请事先与我联

    2024年01月18日
    浏览(30)
  • 约瑟夫环问题

    n n n 个人围成一圈,从第一个人开始报数,数到 m m m 的人出列,再由下一个人重新从 1 1 1 开始报数,数到 m m m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。 注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰 n − 1

    2024年02月02日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包