简单介绍
如果把单链表的最后一个节点的指针指向链表头部,而不是指向NULL,那么就构成了一个单向循环链表,通俗讲就是让尾节点指向头结点。
单向环形链表应用场景:Josephu(约瑟夫、约瑟夫环)问题: 设编号为1, 2, … n的n个人围坐一圈,约定编号为k (1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
代码实现
节点类
class JNode {
private int id;
private JNode next;
public JNode(int id) {
this.id = id;
}
public int getId() {
return id;
}
public JNode getNext() {
return next;
}
public void setNext(JNode next) {
this.next = next;
}
}
链表类(包括节点管理和约瑟夫环问题解决)
class CircleSingleLinkedList {
private JNode first = null;
public void add(int num) {
if (num < 1){
System.out.println("创建个数不符合规定!");
return;
}
JNode curNode = null;
for (int i = 1; i <= num; i++) {
JNode newNode = new JNode(i);
if (i == 1){
first = newNode;
first.setNext(first);
curNode = first;
}else {
curNode.setNext(newNode);
newNode.setNext(first);
curNode = newNode;
}
}
}
public void list(){
if (first == null){
System.out.println("链表为空!");
return;
}
JNode temp = first;
while (true){
System.out.printf("取出节点%d\n",temp.getId());
if (temp.getNext() == first){
break;
}
temp = temp.getNext();
}
}
public void josepfu(int startNode,int count,int num){
if (first == null || startNode < 1 || count < 1 || startNode > num){
System.out.println("链表为空或者输入的参数不符合标准!");
return;
}
for (int i = 0; i < startNode - 1; i++) {
first = first.getNext();
}
JNode helper = first;
while (helper.getNext() != first){
helper = helper.getNext();
}
while (true){
if (helper == first){
break;
}
for (int i = 0; i < count - 1; i++) {
first = first.getNext();
helper = helper.getNext();
}
System.out.printf("节点%d出圈\n",first.getId());
first = first.getNext();
helper.setNext(first);
}
System.out.printf("节点%d为最后一个节点",first.getId());
}
}
测试类
public class JosepfuTest {
public static void main(String[] args) {
CircleSingleLinkedList linkedList = new CircleSingleLinkedList();
linkedList.add(5);
linkedList.list();
System.out.println("===================");
linkedList.josepfu(1,2,5);
}
}
|