目录
public class Node { //节点编号(题中人的编号) private int id; //下一个节点 private Node next; public Node(int id) { this.id = id; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } @Override public String toString() { return "Node{" + "id=" + id + '}'; } }
定义一个头节点,不代表题中任何人的编号;
省略代码在第三部分
public class CSLinkedList { //头节点,编号不计算 public Node first = new Node(-1); /** * 为环形链表添加节点 * @param num 环形链表的节点个数 */ public void addNode(int num){ //代码 } /** * 查看环形链表中所有的节点 */ public void showNode(){ //代码 } /** * 约瑟夫环问题 * @param start 开始报数人的编号:编号为k(1<=k<=n)的人从1开始报数 * @param count 离开时报的数:每数到第m个,该人就要离开此圈,它的下一位又从1开始报数 * @param num 圈内人数:编号是1,2...n的n个人围坐一圈 */ public void josephCircle(int start, int count, int num){ //代码 } }
1、添加节点
/** * 为环形链表添加节点 * @param num 环形链表的节点个数 */ public void addNode(int num){ //判断num if (num < 1){ System.out.println("不符合要求!"); return; } //临时节点 //添加临时节点,只用更改临时节点指向的节点即可,不需要对环形链表中的节点进行复杂操作 Node temp = null; for (int i = 1; i <= num; i++) { //新节点 //从编号1开始,每循环一次,添加一个新节点 Node node = new Node(i); //判断添加方式 if (i == 1){ //第一个节点的添加 //使编号为1的节点为第一个节点,第一个节点的下一个节点指向自身。 first = node; first.setNext(first); //使编号为1的节点指向临时节点,方便以后的添加操作 temp = first; }else { //其它节点的添加 //使临时节点指向新添加的节点 temp.setNext(node); //新添加的节点指向编号为1的节点 node.setNext(first); //使新添加的节点指向临时节点,方便以后操作 temp = node; } } }
2、查看环形链表中的所有节点
public void showNode(){ if (first.getNext() == null){ System.out.println("该环形链表为空!"); return; } Node node = first; while (true){ //输出每一个节点的编号 System.out.printf("编号为%d\n",node.getId()); //节点的下一个节点指向第一个节点时,循环结束 if(node.getNext() == first){ break; } //使节点向后移动 node = node.getNext(); } }
3、约瑟夫环问题相关代码
public void josephCircle(int start, int count, int num){ //判断输入是否正确 if (first == null || start < 1 || count > num){ System.out.println("输入有错误!"); return; } //定义一个结束节点,指向环形链表的最后一个元素 Node end = first; while (end.getNext() != first){ end = end.getNext(); } //定义一个开始节点 //开始报数人的编号为2,则first节点移动2-1次 //first节点移动,结束节点(end)也会移动,移动次数和first节点相同 for (int i = 0; i < start - 1; i++) { first = first.getNext(); end = end.getNext(); } //出列节点 //判断节点个数,只有一个节点 while (end != first){ //判断出列节点 //报3的人出列,first是编号为2的人,则移动3-1次,编号为4的人出列, for (int i = 0; i < count - 1; i++) { first = first.getNext(); end = end.getNext(); } System.out.printf("编号-%d-节点出环形链表!\n",first.getId()); first = first.getNext(); end.setNext(first); } System.out.printf("编号-%d-节点出环形链表!\n",first.getId()); }
public class Test01 { public static void main(String[] args) { Node node1 = new Node(1); CSLinkedList list = new CSLinkedList(); list.addNode(15); list.showNode(); System.out.println("-------------------"); list.josephCircle(1,2,15); } }
测试结果如下:
这是我在书里面看的,书名记不太清,看到就是缘分!
互联网时代,我们即将看到,无创造则无毁灭。
以上仅供学习参考,可能会有不正确的地方,不过问题应该不大吧,注释是我的想法,表述可能有一点点粗糙,希望可以帮助大家!