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 ...
随机推荐
- #dp,齐肯多夫定理#CF126D Fibonacci Sums
题目 \(T(T\leq 10^5)\) 组数据,每次给定数字 \(n(n\leq 10^{18})\), 问有多少种方案将 \(n\) 分解成若干个互不相同的斐波那契数 分析 如果找到一个方案使得所 ...
- OpenHarmony定义组件重用样式:@Styles装饰器
如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在进行重复样式设置,虽然可以复制粘贴,但为了代码简洁性和后续方便维护,我们推出了可以提炼公共样式进行复用的装饰器@Styles. @St ...
- 本周四晚19:00知识赋能第4期直播丨OpenHarmony智能家居项目之设备控制实现
OpenAtom OpenHarmony(以下简称"OpenHarmony")开源开发者成长计划项目自 2021 年 10 月 24 日上线以来,在开发者中引发高度关注. 成长计划 ...
- SQline安装
SQLite 安装 SQLite 的一个重要的特性是零配置的,这意味着不需要复杂的安装或管理.本章将讲解 Windows.Linux 和 Mac OS X 上的安装设置. 在 Windows 上安装 ...
- std::thread 二:互斥量(lock() & unlock())
mutex 互斥量的作用是保护共享数据 *:有 lock() 就一定要有 unlock() #include <iostream> #include <thread> # ...
- Android 开发入门(1)
0x01 准备 (1)概述 安卓(Android)基于 Linux 内核开发的操作系统,由 Google 等领导开发. (2)版本 Android 版本号 API 发布时间 Android 14 - ...
- mongodb基础整理篇————副本原理篇[外篇]
前言 简单介绍一下副本集的原理篇. 正文 下面是几个基本的原理: 副本之间是如何复制的? mongodb 实现此功能的方式是保存操作日志,其中包含了主节点执行的每一次操作,这和mysql比较像. op ...
- java使用Selenium操作谷歌浏览器学习笔记(二)
使用WebDriver操作浏览器之前必须设置对应的driver System.setProperty("webdriver.chrome.driver", "D:\\Ne ...
- 暑期集训 Day11 —— 模拟赛复盘
${\color{Green} \mathrm{Problem\ 1 :Subarray }} $ 签到失败... 直接二进制分组,找出所有二进制位=0 的方法. 死因: 二进制分组没想出来... $ ...
- 【走进RDS】之SQL Server性能诊断案例分析
简介: 数据库性能诊断不仅对其数据库技能要求较高,而且需要大量的前期准备工作,如收集各种性能基线.性能指标和慢SQL日志等,尤其是面对多数据库性能调优时,往往事倍功半. 客户的困扰 前几天某程序员小王 ...