您的位置:首页 > 其它

约瑟夫环问题

2013-10-17 01:20 381 查看

问题描述

设编号为1,2,3 ……,n(n > 0)个人按顺时针方向围坐一圈,没人持有一个正整数密码。开始时任意给出一个报数上限值m,从第一个人开始顺时针方向自 1 起顺序报数,报到 m 时停止报数,报 m 的人出列,并将他的密码作为新的 m 值,从他在顺时针方向上的下一个人开始重新从 1 开始顺序报数;如此下去,直到所有人全部出列为止。
基本要求:设计程序模拟该过程,给出出列人的编号序列。
测试数据:n=7,密码依次为:3,1,7,2,4,8,4,m= 20。

问题分析:

要求输出编号序列,所以得保存每个人的编号;
在出列过程中,要用到该出列人的密码,所以得保存密码。
顺时针方向围坐一圈。
基于以上三点,可以设采用不带头结点单向循环链表。如下:

代码实现:

结点类:

public class Node {
private int no;
private int mima;
private Node next;

public Node(int no, int mima) {
this.no = no;
this.mima = mima;
}

public int getNo() {
return no;
}

public void setNo(int no) {
this.no = no;
}

public int getMima() {
return mima;
}

public void setMima(int mima) {
this.mima = mima;
}

public Node getNext() {
return next;
}

public void setNext(Node next) {
this.next = next;
}
}


不带头结点的单向循环链表类:

//不带头结点的单向循环链表
public class NoHeadOneWayLoopList {
private Node head;
private int currentSize;

public NoHeadOneWayLoopList() {
head = null;
currentSize = 0;
}

// 返回下标为 i 的那个结点的指针,结点编号从0开始;
public Node index(int i) {
if (i >= 0 && i < currentSize) {
Node temp = head;
for (int j = 0; j < i; j++) {
temp = temp.getNext();
}
return temp;
} else {
System.out.println("下标超界!");
return null;
}
}

// 插入结点,使其成为第 i 个结点。
public void insertNode(Node node, int i) {
if (head == null) {
head = node;
head.setNext(head);
} else {
Node temp = index(i - 1);
node.setNext(temp.getNext());
temp.setNext(node);
}
currentSize++;
}

public void deleteNode(int i) {
if (i == 0) {
if (currentSize == 1) {
head = null;
} else {
Node preNode = index(currentSize - 1);
Node deletedNode = preNode.getNext();
head = deletedNode.getNext();
preNode.setNext(head);
deletedNode.setNext(null);
}
} else {
Node preNode = index(i - 1);
Node deletedNode = preNode.getNext();
head = deletedNode.getNext();
preNode.setNext(head);
deletedNode.setNext(null);
}
currentSize--;
}

public Node getHead() {
return head;
}

public void setHead(Node head) {
this.head = head;
}

public int getCurrentSize() {
return currentSize;
}

public void setCurrentSize(int currentSize) {
this.currentSize = currentSize;
}
}

测试类:

public class TestClass {
private static NoHeadOneWayLoopList list;

public static void main(String[] args) {
list = new NoHeadOneWayLoopList();
list.insertNode(new Node(1, 3), 0);
list.insertNode(new Node(2, 1), 1);
list.insertNode(new Node(3, 7), 2);
list.insertNode(new Node(4, 2), 3);
list.insertNode(new Node(5, 4), 4);
list.insertNode(new Node(6, 8), 5);
list.insertNode(new Node(7, 4), 6);
f(list.index(list.getCurrentSize() - 1), 20);
}

public static void f(Node first, int m) {
if (first.getNext() != first) {
for (int i = 0; i < m - 1; i++) {
first = first.getNext();
}
Node deletedNode = first.getNext();
int mima = deletedNode.getMima();
System.out.print(deletedNode.getNo() + "   ");
first.setNext(deletedNode.getNext());
deletedNode.setNext(null);
list.setCurrentSize(list.getCurrentSize() - 1);
f(first, mima);
} else {
System.out.print(first.getNo() + "   ");
}
}
}


输出结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  约瑟夫环问题