单向循环链表
解决约瑟夫环问题
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];