单向环形链表(约瑟夫问题)
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将出圈,最后剩下一个,例如N=5,M=2,出圈的顺序是:2 4 1 5 3。这里使用单向环形链表来处理约瑟夫问题,单向环形链表其实就是在原有单链表的基础上将尾结点指向头结点,从而构成一个单向环形链表。
单向环形链表的构建方法:
(1)定义一个cur辅助指针接收每次创建好的结点,当创建第一个结点时,把first赋给cur。First指向first构成环
(2)把每次创建好的node结点赋给cur(相当于first.next = node)
(3)把每次创建好的node结点指向first构成环
(4)把cur = node后移
单向环形链表的遍历方法:
(1)定义一个辅助指针cur,循环遍历一次输出一次cur
(2)当cur.next == first时退出循环
使用单向链表创建单向环形链表示意图:
约瑟夫问题:
(1)定义n(需要创建的节点) m(需要数多少下) startNO(从第几个开始)
(2)定义一个cur结点,事先放在单向环形链表最后一个结点
(3)将first(头指针)和cur(辅助指针)移动startNo - 1次,为了设定好初始位置
(4)循环遍历进行报数,每次报数时将first(头指针)和cur(辅助指针)移动m - 1次,为了得到报数的位置,将得到的first输出并出圈(first = first.next cur.next = first)
(5)当cur=first此时退出循环
以下为实现代码:
package com.java;
public class Josephu {
public static void main(String[] args) {
CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
circleSingleLinkedList.addNode(5);
circleSingleLinkedList.count(1,2,5);
}
}
class CircleSingleLinkedList {
Node first = null;
public void addNode(int n)
{
if (n < 1){
System.out.println("n的值有误");
return;
}
Node cur = null;
for (int i = 1; i <= n ; i++) {
Node node = new Node(i);
if (i == 1)
{
first = node;
first.next = first;
cur = first;
}else{
cur.next = node;
node.next = first;
cur = node;
}
}
}
public void list()
{
if (first == null)
{
System.out.println("单向环形链表无数据!");
return;
}
Node cur = first;
while (true)
{
System.out.println(cur);
if (cur.next == first)break;
cur = cur.next;
}
}
public void count(int startNo,int m,int n) {
Node cur = first;
if (first == null || startNo < 1 || startNo > m) {
System.out.println("数据有误");
return;
}
while (true)
{
if (cur.next == first)break;
cur = cur.next;
}
for (int i = 0; i < startNo - 1; i++) {
first = first.next;
cur = cur.next;
}
while (true)
{
if (cur == first)break;
for (int i = 0; i < m - 1; i++) {
first = first.next;
cur = cur.next;
}
System.out.println(first);
first = first.next;
cur.next = first;
}
System.out.println("此时最后一个节点为:" + first);
}
}
class Node
{
private int no;
public 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 +
'}';
}
}