单项环形链表
约瑟夫环问题
设编号为1,2,3,...n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,他的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
思路:
用一个不带头结点的循环链表来处理约瑟夫问题:先构成一个有n个节点单项环形链表,然后由k节点起从1开始计数,到m时,把对应节点从链表中删除,然后再从被删除节点的下一个节点开始从1计数,知道最后一个节点从链表中删除算法结束。
代码示例:
public class Josepfu { public static void main(String[] args) { SingleCircleLinkedList singleCircleLinkedList = new SingleCircleLinkedList(); singleCircleLinkedList.Josepfu(1, 2, 5); } } //创建单项环形链表 class SingleCircleLinkedList { //创建一个first节点,当前没有编号 private Node first; /** * @param nums 为环形链表添加几个节点 */ public void createSingleCircleLinkedList(int nums) { if (nums < 1) { System.out.println("nums值不正确"); return; } Node curNode = null; for (int i = 1; i <= nums; i++) { //根据编号创建节点 Node node = new Node(i); if (i == 1) { first = node; first.setNext(first);//构成环 curNode = first;//让curNode指向第一个节点 } else { curNode.setNext(node); node.setNext(first); curNode = node; } } } /** * 遍历当前环形链表 */ public void list() { if (first == null) { throw new RuntimeException("链表为空!"); } Node curNode = first; while (true) { System.out.println(curNode); if (curNode.getNext() == first) { break; } curNode = curNode.getNext(); } } /** * 根据用户的输入来完成约瑟夫环问题 * * @param startNo 表示从编号几开始数 * @param countNum 表示数几下 * @param nums 表示最初有几个人 */ public void Josepfu(int startNo, int countNum, int nums) { if (nums < 1 || startNo < 1 || startNo > nums) { throw new RuntimeException("参数输入有误!"); } createSingleCircleLinkedList(nums); Node pre = first; //使pre指向first节点的前一个节点 while (true) { if (pre.getNext() == first) { break; } pre = pre.getNext(); } //使first和pre先移动到一开始报数的人那里 for (int i = 0; i < startNo - 1; i++) { first = first.getNext(); pre = pre.getNext(); } //当第一个人开始报数时,让first和pre指针同时开始移动countNum-1此,然后first指向的节点出圈 while (true) { if (first == pre) { break; } for (int i = 0; i < countNum - 1; i++) { first = first.getNext(); pre = pre.getNext(); } //这时first指向的节点就是要出圈的节点 System.out.println(first); first = first.getNext(); pre.setNext(first); } //退出循环后,圈中就只剩下一个节点了。 System.out.println(first); } } class Node { private int no; private Node next; public Node(int no) { this.no = no; } public int getNo() { return no; } public void setNo(int no) { this.no = no; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } @Override public String toString() { return "Node{" + "no=" + no + '}'; } }
来源:https://www.cnblogs.com/lee0527/p/12018863.html