1. 数据结构和算法(四)Java实现环形链表

1.1 约瑟夫问题

约瑟夫问题:公元66年,约瑟夫不情愿地参与领导了犹太同胞反抗罗马统治的起义,后来起义失败,他和一些宁死不降的起义者被困于一个山洞之中。罗马将军韦斯巴芗(Vespasian)派人来劝降,他主张投降,其余的人不答应,并以死相逼。最后,约瑟夫提议,与其死在自己的手上,不如死在彼此的手上。因此他便将游戏规则告知众人:N个人围成一圈,从第一个人开始报数,报到m的人被杀,剩下的人继续从1开始报数,报到m的人继续被杀;如此往复,直到剩下最后一个人。他就是运用这个游戏规则最终活了下来,被后人称为约瑟夫环问题。

图解1:

假设n=6,总共有6个人,k=1,从第一个人开始报数,m=5,每次数五个。

图解2:

第一次报数:从一号开始,数五个数,1->2->3->4->5,数完五个数,五号被杀死,第一次报数后,剩余人数如

下。

图解3:

第二次报数: 从被杀死的五号的下一位开始报数,也就是六号,数五个数,6->1->2->3->4,数数完毕,四号被杀死,第二次报数后,剩余人数如下。

图解4:

第三次报数: 从被杀死的四号的下一位开始报数,同样是六号,数五个数,6->1->2->3->6,数数完毕,六号被杀死,第三次报数后,剩余人数如下。

图解5:

第四次报数: 从被杀死的六号的下一位开始报数,也就是一号,数五个数,1->2->3->1->2,数数完毕,二号被杀死,第四次报数后,剩余人数如下。

图解6:

第五次报数: 从被杀死的二号的下一位开始报数,也就是三号,数五个数,3->1->3->1->3,数数完毕,三号被杀死,只剩下一号,最后活下来的是1号。

1.2 约瑟夫JAVA实现

现实思路:

创建出n个节点的环形链表,即n = 5。代表生成5个人。

需要创建两个变量,分别为first和last分别指向,第一个人和第一个的上一个人。在报数前,先让first和last分别移动k-1次。

将first指向的人杀死,并打印杀死的人号码。当前first == last时,说明游戏结束最后一个人活了下来。

数据结构-代码:

package com.yuanxw.datastructure.chapter4;

/**

* 环形链表

*/

public class Person {

// 编号

private int number;

// 下一个报数的人

private Person next;

public int getNumber() {

return number;

}

public void setNumber(int number) {

this.number = number;

}

public Person getNext() {

return next;

}

public void setNext(Person next) {

this.next = next;

}

}

环形链表-代码:

package com.yuanxw.datastructure.chapter4;

/**

* 自定义 环形链表

*/

public class CustomCyclicLinkedList {

public Person first = null;

public Person last = null;

private int size = 0;

/**

* 生成人员环形列表

*

* @param n

* @return

*/

public boolean builder(int n) {

if (n < 1) {

throw new RuntimeException("参数n必须大于1。");

}

for (int i = 1; i <= n; i++) {

Person person = new Person();

person.setNumber(i);

if (i == 1) {

first = person;

first.setNext(first);

last = first;

} else {

last.setNext(person);

person.setNext(first);

last = person;

}

}

size = n;

return true;

}

/**

* @param n 从第n个人开始报数

* @param m 每次隔几个人

* @return

*/

public String kill(int n, int m) {

StringBuilder builder = new StringBuilder();

if (first == null) {

throw new RuntimeException("约瑟夫环中没有人员,杀人结束!");

}

if (n <= 0 || n > size) {

throw new RuntimeException(String.format("报数开始的位置,必须在1-%s之间!", size));

}

if (m <= 0 || m > size) {

throw new RuntimeException(String.format("约瑟夫环隔数,必须在1-%s之间!", size));

}

// 设置从位置n做为起点进行:报数

for (int i = 0; i < n-1; i++) {

first = first.getNext();

last = last.getNext();

}

while (true){

// first == last 说明只剩下一个人了

if(first == last){

break;

}

// 移动到 m-1的位置。自已本身也需要报数。所以m-1

for (int i = 0; i < m-1; i++) {

first = first.getNext();

last = last.getNext();

}

builder.append(first.getNumber()).append("->");

// 直接杀死移动后first位置

first = first.getNext();

last.setNext(first);

}

return builder.substring(0,builder.length()-2);

}

/**

* 获得 幸存者

* @return

*/

public int getSurvivor(){

return first.getNumber();

}

@Override

public String toString() {

StringBuilder builder = new StringBuilder();

Person current = first;

builder.append("[");

do {

builder.append(current.getNumber()).append(",");

current = current.getNext();

} while (current != first);

builder.deleteCharAt(builder.length() - 1);

builder.append("]");

return builder.toString();

}

}

测试部分-代码

package com.yuanxw.datastructure.chapter4;

public class JosephusProblem {

public static void main(String[] args) {

CustomCyclicLinkedList customCyclicLinkedList = new CustomCyclicLinkedList();

customCyclicLinkedList.builder(6);

System.out.println("列出约瑟夫环列表:" + customCyclicLinkedList);

System.out.println("杀人的顺序:" + customCyclicLinkedList.kill(1,5));

System.out.println("最后幸存者是:" + customCyclicLinkedList.getSurvivor());

}

}

执行结果:

列出约瑟夫环列表:[1,2,3,4,5,6]

杀人的顺序:5->4->6->2->3

最后幸存者是:1

– 以上为《数据结构和算法(四)Java实现环形链表》,如有不当之处请指出,我后续逐步完善更正,大家共同提高。谢谢大家对我的关注。

——厚积薄发(yuanxw)

java环形链表_数据结构和算法(四)Java实现环形链表相关推荐

  1. java红包记录_微信红包算法(java)

    package com.example.ant.common.tools; import java.util.LinkedList; import java.util.List; /** * 描述:红 ...

  2. java二叉排序树_数据结构与算法—二叉排序树(java)

    前言 前面介绍学习的大多是线性表相关的内容,把指针搞懂后其实也没有什么难度.规则相对是简单的. 再数据结构中树.图才是数据结构标志性产物,(线性表大多都现成api可以使用),因为树的难度相比线性表大一 ...

  3. java实现数据挖掘_数据挖掘Apriori算法的java实现

    对于Apriori算法,Apriori算法是一种挖掘关联规则的频繁项集算法,在很多领域中应用广泛. 它的算法思想是: 1先找到所有的小频繁项集, 2然后做连接步骤,将小频繁项集拼接作为候选集, 3然后 ...

  4. java数据结构与算法之顺序表与链表深入分析

    转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52953190 出自[zejian的博客] 关联文章: java数据结 ...

  5. 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)

    常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...

  6. 数据结构与算法【Java版】:第一课

    目录 数据结构和算法简介 稀疏数组 队列 链表 bilibili尚硅谷韩顺平老师课程的笔记.https://b23.tv/4YU0Mz 数据结构和算法简介 数据结构与算法的重要性: 算法是程序的灵魂, ...

  7. 黑马程序员 C语言数据结构与算法之线性表(链表/栈/队列/顺序表)

    C语言 链表基础知识清晰讲解(黑马) 讲的蛮好,就是音质不太好,有时听不清讲的啥! [黑马]数据结构与算法之线性表(链表/栈/队列/顺序表)[配套源码 嘛蛋,看错了,这是java的... 文章目录 链 ...

  8. 数据结构与算法【Java】06---七大查找算法总结

    文章目录 数据结构与算法[Java]06---查找算法总结 1.查找算法简介 1.1.查找的定义 1.2.查找算法分类 1.3.常用查找算法 2.线性查找算法 2.1.线性查找简介 2.2.线性查找代 ...

  9. Python数据结构与算法(附录)——块状链表的动态调整

    Python数据结构与算法(附录)--块状链表的动态调整 块状链表的动态调整 违反规则 1 违反规则 2 相关链接 块状链表的动态调整 我们已经知道块状链表的块的最大容量会随着链表长度的变化动态改变, ...

最新文章

  1. 配置和使用OCS 2007会议功能
  2. python easygui进度条_Python _easygui详细版
  3. C++学习之路 | PTA乙级——1092 最好吃的月饼 (20 分)(精简)
  4. 大数据开发:剖析Hadoop和Spark的Shuffle过程差异
  5. 2019帝豪gs装软件_继悬浮式车顶之后,2019年这些设计将会成为主流!
  6. css hack 尽我所见
  7. 模拟电子放大电路分析
  8. H5与客户端交互的方式有哪些? 怎么做?
  9. 2018年中国互联网企业百强榜单揭晓
  10. RocksDB调优指南
  11. 语音识别 | 数据堂方言语音数据集
  12. 基于用户的产品分析之Cohort Analysis(群组分析,留存分析)
  13. mathtype在word出现宏被禁止的错误 终于解决
  14. CEOI 2020, Day 2 A,B题解 CF1403A CF1403B
  15. 《Head First 设计模式》笔记
  16. 【射影几何06】齐次坐标下“点-线”几何表示
  17. 用KooMail轻松实现本地收取Hotmail/MSN/Live邮件
  18. 【第十一章】提炼子类/超类/接口/类
  19. 购买运虚拟主机还是云服务器,购买运虚拟主机还是云服务器
  20. 他狂骗五千万美元消失17年...却被一个纪录片导演锲而不舍的追到了镜头前!...

热门文章

  1. javascript事件机制与jQuery.bind的补充说明
  2. 目前我们再用的即时通讯软件
  3. ATL offsetofclass 的工作原理
  4. 再见了,余!额!宝!!!
  5. cad图纸问号怎么转换文字_CAD打开图纸后字体显示为问号,这样解决治标治本(送)...
  6. 无代码绘制基因表达箱线图
  7. 机器学习第20篇 - 基于Boruta选择的特征变量构建随机森林
  8. Randomatic mac - AE随机摆动的字母图层效果脚本
  9. android studio 设置自动编译_Appium Mac系统 自动测试环境搭建
  10. 11届蓝桥杯青少年组C++全国赛高级组 八.编程实现:计数(python3实现)