引子

据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。

进入正题

约瑟夫环问题,在计算机界是一个经典的循环链表问题,题意是:已知 n 个人(分别用编号 1,2,3,…,n 表示)围坐在一张圆桌周围,从编号为 k 的人开始顺时针报数,数到 m 的那个人出列;他的下一个人又从 1 开始,还是顺时针开始报数,数到 m 的那个人又出列;依次重复下去,直到圆桌上剩余一个人。

如图所示,假设此时圆周周围有 5 个人,要求从编号为 3 的人开始顺时针数数,数到 2 的那个人出列:

出列顺序依次为:

编号为 3 的人开始数 1,然后 4 数 2,所以 4 先出列;

4 出列后,从 5 开始数 1,1 数 2,所以 1 出列;

1 出列后,从 2 开始数 1,3 数 2,所以 3 出列;

3 出列后,从 5 开始数 1,2 数 2,所以 2 出列;

最后只剩下 5 自己,所以 5 胜出。

手敲代码实现如下

#include "stdlib.h"

#define OK 1

#define ERROR 0

typedef int ElemType;

typedef int Status;

typedef struct Node{

ElemType data;

struct Node *next;

}Node;

typedef struct Node * LinkList;

/*

1、初始化单向循环链表(带入节点总数)

*/

Status initJosehuList(LinkList *list, int count){

LinkList tempNode,lastNode = NULL;

int i = 1;

while (i <= count) {

//创建一个节点

tempNode = malloc(sizeof(Node));

if (tempNode == NULL) {

return ERROR;

}

tempNode->data = i;

if (*list == NULL) {

//首元节点插入

*list = tempNode;

tempNode->next = tempNode;

}

else {

//尾节点插入

tempNode->next = lastNode->next;

lastNode->next = tempNode;

}

//记录尾节点

lastNode = tempNode;

i++;

}

return OK;

}

/*

2、遍历链表

循环链表的遍历最好用do while语句,因为需要先做一次p = p->next,判断p->next等于首元节点的时候就是找到尾节点了

*/

void ListTraverse(LinkList list){

printf("遍历链表:");

LinkList p = list;

if (!p) {

printf("这是一个空链表");

}

else {

do {

printf("%d ",p->data);

p = p->next;

} while (p != list);

}

printf("\n");

}

int JosehuMethod(LinkList *list,int startIndex,int num){

if (*list == NULL || startIndex < 1 || num < 1) {

return 0;

}

//找到最后面的那个人,因为他是index为1时第一个数数的人的前一个人

LinkList preNode;

for (preNode = *list; preNode->next != *list; preNode = preNode->next);

//记录要出列的人

LinkList locaNode;

//第几次出列

int serialNum = 1;

//记录报到几号了

int newNum = 1;

//判断是否只留下一个人了

while ((*list)->next != *list) {

//1、先找到开始报数的人

if (startIndex > 1) {

preNode = preNode->next;

startIndex --;

continue;

}

//2、找到后,让他开始报数

if (newNum < num) {

newNum ++;

preNode = preNode->next;

}

else {

//3、找到要出列的人,将他出列

newNum = 1;

locaNode = preNode->next;

//判断是否首元节点,要特殊处理下

if (locaNode == *list) {

*list = locaNode->next;

}

preNode->next = locaNode->next;

printf("第%d个出列的人是:%d\n",serialNum,locaNode->data);

serialNum ++;

free(locaNode);

}

}

printf("最后留下的人是:%d\n",(*list)->data);

return (*list)->data;

}

int main(int argc, const char * argv[]){

//初始化

LinkList list;

int count;

printf("输入队列数量:");

scanf("%d",&count);

initJosehuList(&list, count);

//遍历数据

ListTraverse(list);

int startIndex;

int num;

printf("输入开始报数的位置:");

scanf("%d",&startIndex);

printf("输入出列的报数序号:");

scanf("%d",&num);

//执行约瑟夫方法

JosehuMethod(&list, startIndex, num);

printf("\n");

return 0;

}

复制代码

输入效果如下

约瑟夫环c语言程序完整版,约瑟夫环的C语言实现相关推荐

  1. 约瑟夫环c语言程序完整版,C语言:约瑟夫环问题(源代码)

    本帖最后由 geige 于 2015-7-26 00:48 编辑 #include #include struct stu //构建一个新的数据类型 { int num; struct stu *ne ...

  2. c语言删除双向链表重复元素,求一个双向链表的建立,插入删除的c语言程序完整版的,借鉴一下思想,再多说一下就是能运行的那种...

    最佳答案 //链表的操作编辑 //线性表的双向链表存储结构 typedef struct DuLNode { ElemType data; struct DuLNode *prior,*next; } ...

  3. 约瑟夫环(c语言程序完整版)

    约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3-n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列: ...

  4. 约瑟夫环数据结构c语言程序,数据结构的C语言(类C语言)--单向循环链表--约瑟夫环...

    代码区 约瑟夫环:用类C语言实现!!!可以成功运行!!!不是仅仅的算法,而是实实在在的类C #include #include typedef int ElemType; typedef struct ...

  5. 程序员面试系列——约瑟夫环

    约瑟夫斯问题(Josephus Problem) 约瑟夫斯问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为"约瑟夫环",也 ...

  6. # R语言——约瑟夫环

    约瑟夫环: n个人围成一个圈,从第一个人点名,每数到第三个人,这个人移出圈外, 依次类推,求最后留下来的人编号是? 思路:每次循环重新编码序号作为names,并根据names 进行筛选 拓展:约瑟夫环 ...

  7. 约瑟夫环c语言代码 指针,约瑟夫环C语言实现源代码(1)

    前天笔试有个约瑟夫环的问题,怪不得人家没通知我面试,原来我的约瑟夫环做的确实有问题,昨天晚上又重新做了下,下面上源代码: /* file:osephu.cpp author:www.5dkx.com ...

  8. c语言学生作业ppt课件怎么做,C语言课件完整版(精华).ppt

    <C语言课件完整版(精华).ppt>由会员分享,可在线阅读,更多相关<C语言课件完整版(精华).ppt(484页珍藏版)>请在人人文库网上搜索. 1.1,计算机程序设计基础(C ...

  9. c语言 精华,C语言课件完整版(精华)

    <C语言课件完整版(精华)>由会员分享,可在线阅读,更多相关<C语言课件完整版(精华)(484页珍藏版)>请在人人文库网上搜索. 1.1 .计算机计程仪编程基础(习语言),2, ...

  10. 浙江高考VB之约瑟夫环

    浙江信息技术Giao考之 "约瑟夫环" 在浙江信息技术高考中,有一种题型叫做 约瑟夫环题; 首先,约瑟夫环是什么东西? 鲜活的栗子: 我们现在有6个小朋友,分别标号为1 ~ 6.从 ...

最新文章

  1. 【神经网络】(16) MobileNetV3 代码复现,网络解析,附Tensorflow完整代码
  2. 广域网设备:远程路由器/交换机/服务器—Vecloud
  3. 通过xrdp远程访问ubuntu出现输入d最小化问题的处理
  4. c语言命令行选项处理函数getopt和getopt_long() 函数使用
  5. Linux配置最基础的命令
  6. 3、数据库中的字符集和校对集
  7. SqlServe中使用EXEC @sql 来传递table变量
  8. 终端如何查看虚拟环境_Python版本管理工具和虚拟环境
  9. android n进入分屏代码分析_完全不用鼠标写代码!你信么?[视频]
  10. L298N芯片驱动电机
  11. 人工智能会取代程序员吗?
  12. 关于微信小程序中的.eslintrc.js
  13. 操作系统课设——Windows 进程管理
  14. W-Hive 支持苹果 iOS16 新版本
  15. 腾讯43亿QQ号码用完后怎么办?
  16. 《工程伦理与学术道德》之《工程中的价值、利益与公正》
  17. 浅谈linux - 内核时间的处理
  18. 2019天梯赛第四次训练赛
  19. LogStash 7.x com.mysql.cj.jdbc.Driver not loaded的解决方法
  20. pyqt5 源码 eric 记录

热门文章

  1. Linux的使用注意事项
  2. c语言入门经典+第5版+习题答案,《C语言入门经典(第5版)》—甲虎网一站式图书批发平台...
  3. Delphi入门教程
  4. SQL Server 2005 Service Pack 4 下载地址
  5. Linux chmod 命令 设置权限
  6. VC6.0 MSDN下载地址 msdn oct 2001光盘下载(可下载)
  7. Office机器人2.1.763.557(Excel批量打印 Word批量打印 批量加密 批量解密 批量转换格式)...
  8. 【数据结构 严蔚敏版】 链式栈基本操作
  9. java视频教程之Java小白学习方法
  10. PDFLib库的使用c++