单向循环链表
解决约瑟夫环问题
1.构造方法 及字段
public CircleLinkedList() {
}
private Node first;
2.获取有效节点数
public int elementsCount() {
int result = 0;
for (Node currentNode = this.first; ; currentNode = currentNode.next) {
result++;
if (currentNode.next == this.first)
break;
}
return result;
}
3.判断循环链表是否为空
public boolean isEmpty() {
return this.first == null;
}
4.获取倒数第一个节点和倒数第二个节点
public Node getBeforeNode(int offset) {
Node currentNode = first;
while (currentNode.next != this.getIndexNode(offset)) {
currentNode = currentNode.next;
}
return currentNode;
}
public Node getLastNode() {
Node currentNode = first;
while (currentNode.next != first) {
currentNode = currentNode.next;
}
return currentNode;
}
5.添加新节点
public void add(String item) {
if (isEmpty()) {
first = new Node(item);
first.next = first;
return;
}
Node node = new Node(item, this.first);
Node lastNode = getLastNode();
lastNode.next = node;
}
6.根据位置获取节点
public Node getIndexNode(int index) {
if (index < 0 || index >= elementsCount())
throw new IndexOutOfBoundsException("偏移量非法:" + index);
Node result = this.first;
for (int i = 0; i < index; i++) {
result = result.next;
}
return result;
}
7.根据起始偏移量beginNo和间隔gap实现约瑟夫环的循环输出节点内容到字符串
public String[] getAll(int beginNo, int gap){
if(this.first == null)
System.out.println("链表为空无法完成出列。");
int currentElementsCount = this.elementsCount();
if(beginNo < 1 || beginNo > currentElementsCount)
throw new IndexOutOfBoundsException("起始位置输入有误:" + beginNo);
Node temp = this.getLastNode();
for(int i = 0; i < beginNo - 1; i ++){
this.first = this.first.next;
temp = temp.next;
}
String[] result = new String[currentElementsCount];
int resultArrayIndex = 0;
while (true) {
if(temp == this.first)
break;
for (int i = 0; i < gap - 1; i ++){
this.first = this.first.next;
temp = temp.next;
}
result[resultArrayIndex ++] = this.first.item;
this.first = this.first.next;
temp.next = this.first;
}
result[resultArrayIndex ++] = this.first.item;
return result;
}
8.重写toString 方法,实现打印单向循环链表中的元素
@Override
public String toString() {
if (isEmpty())
return "[]";
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[--");
for (Node currentNode = this.first; ; currentNode = currentNode.next) {
stringBuilder.append(currentNode.item);
if (currentNode.next == this.first) {
stringBuilder.append("--]");
break;
}
stringBuilder.append(",");
}
return stringBuilder.toString();
}
9.静态的节点内部类
public static class Node {
public Node() {
}
public Node(String item) {
this.item = item;
}
public Node(String item, Node next) {
this.item = item;
this.next = next;
}
private String item;
private Node next;
public String getItem() {
return item;
}
}
10.总体实现
package com.circle.util;
import java.util.Arrays;
public class CircleLinkedList {
public CircleLinkedList() {
}
private Node first;
public int elementsCount() {
int result = 0;
for (Node currentNode = this.first; ; currentNode = currentNode.next) {
result++;
if (currentNode.next == this.first)
break;
}
return result;
}
public boolean isEmpty() {
return this.first == null;
}
public Node getBeforeNode(int offset) {
Node currentNode = first;
while (currentNode.next != this.getIndexNode(offset)) {
currentNode = currentNode.next;
}
return currentNode;
}
public Node getLastNode() {
Node currentNode = first;
while (currentNode.next != first) {
currentNode = currentNode.next;
}
return currentNode;
}
public void add(String item) {
if (isEmpty()) {
first = new Node(item);
first.next = first;
return;
}
Node node = new Node(item, this.first);
Node lastNode = getLastNode();
lastNode.next = node;
}
public Node getIndexNode(int index) {
if (index < 0 || index >= elementsCount())
throw new IndexOutOfBoundsException("偏移量非法:" + index);
Node result = this.first;
for (int i = 0; i < index; i++) {
result = result.next;
}
return result;
}
public String[] getAll(int beginNo, int gap){
if(this.first == null)
System.out.println("链表为空无法完成出列。");
int currentElementsCount = this.elementsCount();
if(beginNo < 1 || beginNo > currentElementsCount)
throw new IndexOutOfBoundsException("起始位置输入有误:" + beginNo);
Node temp = this.getLastNode();
for(int i = 0; i < beginNo - 1; i ++){
this.first = this.first.next;
temp = temp.next;
}
String[] result = new String[currentElementsCount];
int resultArrayIndex = 0;
while (true) {
if(temp == this.first)
break;
for (int i = 0; i < gap - 1; i ++){
this.first = this.first.next;
temp = temp.next;
}
result[resultArrayIndex ++] = this.first.item;
this.first = this.first.next;
temp.next = this.first;
}
result[resultArrayIndex ++] = this.first.item;
return result;
}
public void print() {
if (isEmpty())
System.out.println("空");
Node cntNode = this.first;
while (cntNode.next != first) {
System.out.println(cntNode.item);
cntNode = cntNode.next;
}
System.out.println(cntNode.item);
}
@Override
public String toString() {
if (isEmpty())
return "[]";
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[--");
for (Node currentNode = this.first; ; currentNode = currentNode.next) {
stringBuilder.append(currentNode.item);
if (currentNode.next == this.first) {
stringBuilder.append("--]");
break;
}
stringBuilder.append(",");
}
return stringBuilder.toString();
}
public static class Node {
public Node() {
}
public Node(String item) {
this.item = item;
}
public Node(String item, Node next) {
this.item = item;
this.next = next;
}
private String item;
private Node next;
public String getItem() {
return item;
}
}
}
11.测试类
package com.circle.test;
import com.circle.util.CircleLinkedList;
import java.util.Arrays;
public class Demo1 {
public static void main(String[] args) {
CircleLinkedList circleLinkedList = new CircleLinkedList();
circleLinkedList.add("宫本1");
circleLinkedList.add("宫本2");
circleLinkedList.add("宫本3");
circleLinkedList.add("宫本4");
System.out.println("-------------");
String[] strings = circleLinkedList.getAll(1,4);
System.out.println(Arrays.toString(strings));
}
}
输出结果:[宫本4, 宫本1, 宫本3, 宫本2];