C语言:约瑟夫问题——使用循环链表解决
传说有30个乘客同乘一条船,因为严重超载,加上风浪水作,危险万分。船长告诉乘客,只有将全船一半的乘客投入海 中,其余人才能幸免于难。他们约定了一个规则:30个人围成一圈,由第一个人数起,依次报数,数到第9个人,便把他投入大海中,然后再从他的下一个人数起,数到第9个人,再将其扔下大海,如此循环地进行,直到剩下15个乘客为止。请问哪些位置是将被扔下大海的位置,留下的是谁。
(由这个传说产生了约瑟夫问题,总数n,删除数为k)
最后我写了一个函数是将结果输出到外部文本txt中。
我所写出的循环链表是基于单链表来写的:简而言之就是,首先,生成我们所学过的单链表(我这里采用的是头插法),每次生成一个空间,就将该空间的成员信息进行赋初值,也就是把结构里面所定义的成员的位置信息进行赋值(如:第一个成员的位置信息就是1,接下去就是2,3,4....)
PS:需要注意的是,我这里是头插法,所以我在位置信息的时候是从30开始,最后整个单链表生成之后就是从1开始的一个正向顺序的链表。 当然你也可以选择把整个单链表生成之后再进行赋值,这样可能会更清晰,我这里是边想边写,就没有考虑到这么多。
准备工作完成之后,你就可以把单链表的尾部指针,和头部指针,将这两个指针连接起来(尾部指针就是指向NULL的那个指针),记住一定是尾部指针指向头部指针,也就是把头部指针赋值给尾部指针,千万不能把头部指针指向尾部,因为这样的话你就是把你的单链表结构破坏掉了。
最后是输出环节,看过我文章 的小伙伴应该都知道,想要输出内容到txt文本流应该要用fprintf,不然你就是大冤种,在输出中文字符的时候没有用fprintf就会乱码,当然我这里没有输出中文字符,但是养成好习惯,在当你想输出文本流的时候一般情况下都建议你去使用fprintf。
(忘记了的朋友可以看看我这篇博客的文字部分:http://t.csdn.cn/Pue8v)
下面是源代码:
(耐心看完,不懂得可以留言,我知道的话都会回复的,毕竟讨论代码是更能让人记忆深刻)
#include<stdio.h>
#define PF(format,...) printf(#format, ##__VA_ARGS__)
#include<stdlib.h>
int n = 30;//总数
int k = 9; //待删除的总数
/*
循环链表, 从头开始,
判断总数是否小于n/2个,
a)不是那就每数到第k个就删除节点
指向下一个节点
b)如果小于等于n/2那就退出,将链表中生剩下的元素打印进txt文件
*/
typedef struct _circu_link{
int index;//成员下标
int member;//成员
struct _circu_link *next;
}circu_link;
circu_link *mem_H = NULL;//成员信息
void Initmember();//初始化结构
void Delete_mem();//删除信息
void PF_result();
void Put_TXT();
void Release_mem();
int main(void)
{
Initmember();//初始化
Delete_mem();//符合条件的成员将其删除
PF_result();//打印结果
Put_TXT();//将结果存到外部txt文件
Release_mem();
return 0;
}
void Initmember()//初始化结构
{
circu_link *temp, *new_member;
int i;
for(i = n; i >= 1; i--)
{
new_member = (circu_link*)malloc(sizeof(circu_link));
if(new_member == NULL)
{
PF(分配内存失败!\n);
exit(1);
}
if(mem_H == NULL)
{
mem_H = new_member;
new_member->index = i;
new_member->next = NULL;
}
else
{
temp = mem_H;
mem_H = new_member;
new_member->index = i;
new_member->next = temp;
}
}
temp = mem_H;
while(temp->next != NULL)
{
temp = temp->next;
}
temp->next = mem_H;//生成循环链表
// temp = mem_H;
// for(i = 0; i < 60; i++)
// {
// PF(%d****, temp->index);
// temp = temp->next;
// }
}
void Delete_mem()
{
circu_link *previous = NULL, *current, *temp;;
current = mem_H;
int i = 0, count = 0;
while(1)
{
if(i >= n/2)//判断是否已经删除掉n/2的成员
{
break;
}
else
{
count++;
previous = current;
current = current->next;
}
if(count == k-1)
{
count = 0;
i++;
temp = current;
previous->next = current->next;//删除
free(temp);
current = previous->next;
}
}
}
void PF_result()
{
circu_link *temp;
int i;
temp = mem_H;
PF(大难不死的成员如下:\n);
for(i = 0; i < n/2; i++)
{
PF(-%d-, temp->index);
temp = temp->next;
}
PF(\n);
}
void Put_TXT()
{
FILE *fp = NULL;
circu_link *temp = mem_H;
int i;
fp = fopen("D:/D/约瑟夫问题/Put.txt", "w");
for(i = 0; i < n/2; i++)
{
fprintf(fp, "%d-",temp->index);
temp = temp->next;
}
fclose(fp);
}
void Release_mem()
{
int i;
circu_link *temp = NULL;
for(i = 0; i < n/2; i++)
{
temp = mem_H;
mem_H = mem_H->next;
free(temp);
}
}
外部文件也同样生成了:
C语言:约瑟夫问题——使用循环链表解决的更多相关文章
- C++循环链表解决约瑟夫环问题
约瑟夫环问题可以简单的使用数组的方式实现,但是现在我使用循环链表的方法来实现,因为上午看到一道面试题规定使用循环链表解决约瑟夫环问题. 什么是约瑟夫环? “约瑟夫环是一个数学的应用问题:已知n个人(以 ...
- C语言单向循环链表解决约瑟夫问题
据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,4 ...
- golang数据结构之用循环链表解决约瑟夫环问题
josephu.go package link import ( "fmt" ) type Kid struct { ID int next *Kid } func AddKid( ...
- 约瑟夫环问题-循环链表VS数组
2013-08-18 21:27:50 循环链表.数组解决约瑟夫环问题的比较 注意几点: 循环链表的建立不难,在删除循环链表中元素时,用pCur->next != pCur判断结束: 每一轮计数 ...
- 约瑟夫环的java解决
总共3中解决方法,1.数学推导,2.使用ArrayList递归解决,3.使用首位相连的LinkedList解决 import java.util.ArrayList; /** * 约瑟夫环问题 * 需 ...
- 【IE兼容性】代码中多语言样式+IE不兼容解决
一.代码中样式根据不同语言对IE做不兼容解决 二.代码逻辑: 1. 后台返回语言信息: result.addObject("language",getLocaleStr()); ...
- 【C语言教程】“双向循环链表”学习总结和C语言代码实现!
双向循环链表 定义 双向循环链表和它名字的表意一样,就是把双向链表的两头连接,使其成为了一个环状链表.只需要将表中最后一个节点的next指针指向头节点,头节点的prior指针指向尾节点,链表就能成环儿 ...
- Titanium中调用ios组件时语言不是本地化的解决方法
用Titanium开发的ios应用中,当调用系统组件时,尽管手机已经设置了系统语言为中文,但那些组件的界面却仍为英文.比如调用iphone中的相册组件,其界面为: 那么怎么让它跟系统语言保持一致呢? ...
- [转载]VS2012编译C语言scanf函数error的解决方法
在VS 2012 中编译 C 语言项目,如果使用了 scanf 函数,编译时便会提示如下错误: error C4996: 'scanf': This function or variable may ...
- C语言 约瑟夫圈问题:N个人围成一圈,从第一个人开始按顺序报数并编号1,2,3,……N,然后开始从第一个人转圈报数,凡是报到3的退出圈子。则剩下的最后一个人编号是多少。
样例输入3 输出2 输入100 输出91 代码及分析: #include<stdio.h> int main() { int i,n,N,out,a[1000]; out=i=n=0 ...
随机推荐
- #分治#JZOJ 4211 送你一颗圣诞树
题目 有\(m+1\)棵树分别为\(T_{0\sim m}\),一开始只有\(T_0\)有一个点,编号为0. 对于每棵树\(T_i\)由T_{a_i}\(的第\)c_i\(个点与\)T_{b_i}\( ...
- keycloak~网站对接到Keycloak的步骤
新网站对接到KC的部署 kc的环境 向kc申请自己的客户端 kc的登录接口 通过code换token接口 刷新token接口 kc的用户信息接口 kc的jwt token说明 1. kc的环境 测试环 ...
- 代码覆盖率检查工具 -- Coverage,简单使用
Coverage 一个专门用来检查代码覆盖率的工具,他的使用非常简单,有两种使用方法:[命令行运行,配合测试套件使用] 安装: pip install coverage 一.准备素材 main.py ...
- Openstack之工作流程
组件 OpenStack的核心部件即包括Nova(用于计算).Keystone(用于身份服务).Neutron(用于网络和地址管理).Cinder(块存储).Swift(对象存储).Glance(镜像 ...
- Mysql之innodb架构
Innodb存储引擎的架构 内存结构 Bufer Pool 缓冲池是主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载 ...
- 【6】Spring JavaConfig和常见Annotation
Java 5 的推出,加上当年基于纯 Java Annotation 的依赖注入框架 Guice 的出现,使得 Spring 框架及其社区也"顺应民意",推出并持续完善了基于 Ja ...
- docker 应用篇————mysql容器[十二]
前言 简单介绍一下mysql容器. 正文 这里简单介绍一下mysql的容器. hub.docker.io给了我们一个启动的示例. docker run --name some-mysql -e MYS ...
- c# Barrier 线程回调
前言 假如现在有一个这样的需求,我一堆小黄人生产小黄丹,而大黄人要一直吃小黄丹. 如果是这样的话,想到就是一堆小黄人作为一个多线程,然后一直制造,然后另外一个大黄人一直检索是否有小黄丹,有就吃掉. 但 ...
- Vue 3 进阶用法:异步组件
一.代码分割 一个大型前端应用,如果所有代码都放在单一文件,体积会特别大,下载时间长,白屏时间久,用户体验差. 代码分割是一种有效的优化方式.提前把代码切分为多个小块,只下载当前必需的部分,用到哪块下 ...
- llm构建数据标注助手
为什么要用LLM构建数据标注工具 在LLM出现之前,传统的深度学习模型(包括CV和NLP)就已经需要大量的数据进行训练和微调.没有足够的数据,或者数据需要进行二次加工(比如标签标注),这些问题都成为限 ...