但链表类节点数据没有使用引用类型,使用int类型表示
单链表类:
package Class.LinkList;
public class LinkList {
public Node head;
/*
链表:
1. head是一个在链表外的Node对象,头节点不算在链表内,且头节点不算在长度内
2. 链表其实是多个Node类型的数据链接一起
3. 链表的最后一个节点的nextNode属性为null
*/
// 构造方法一:链表为空链表,只有一个头节点
// 因为是int类型, 头指针指向节点其实有默认值0
public LinkList() {
head = new Node();
}
// 构造方法二:数组传值,形成单链表
// 以数组形式传值. 这里是int数组
// 没有考虑传值数组内值为空的情况(因为为Int类型)
public LinkList(int[] arr) {
this();
Node rear = head; // 尾指针,便于数组传值
for (int i = 0; i < arr.length; i++) {
// rear.toNextNode() = new Node(arr[i], null);
// 一开始把nextNode设为private, 但这样会报错???
rear.nextNode = new Node(arr[i], null);
rear = rear.nextNode;
}
}
// 构造方法三:链表内有一个Node节点
public LinkList(int m) {
head = new Node(0, null);
head.nextNode = new Node(m, null);
}
public boolean isEmpty() {
return head.nextNode == null;
}
// 遍历链表,直到rear指针指向null
public int LinkLength() {
Node rear = head;
int length = 0;
while (rear.nextNode != null) {
length++;
rear = rear.nextNode;
}
return length;
}
// 获得第n个节点的值,同样需要遍历
/*
假设需要获得第2个节点的值,需要把rear指针指向第二个节点
即需要遍历2次 --> 获得第n个节点的值需要遍历n次
*/
public int getInfo(int n) {
Node rear = head;
for (int i = 0; i < n; i++) {
rear = rear.nextNode;
}
return rear.getInt();
}
// 输出单向链表
public void showAllNum() {
Node rear = head;
for (int i = 1; i <= this.LinkLength(); i++) {
System.out.print(this.getInfo(i) + "\t");
}
System.out.println("");
}
}
约瑟夫环类和主类:
package Class.Josephus;
import Class.LinkList.LinkList;
import Class.LinkList.Node;
public class Josephus_LinkList {
private LinkList linkList; // 单链表属性
public Josephus_LinkList(LinkList linkList) {
this.linkList = linkList;
}
public int getSurvivor(int start, int distance) {
// front指针指向待删除节点的前驱节点
Node front = linkList.head;
// front指针初始化
for (int i = 0; i < start; i++) {
front = front.nextNode;
}
while (linkList.LinkLength() > 1) {
// 指针移动,循环用于到达前驱节点
for (int i = 0; i < distance - 1; i++) { // distance = 3, 遍历 2 次
front = front.nextNode;
// 如果front指向null, 则指向头节点
if (front == null) {
front = linkList.head.nextNode;
}
}
// 如果front指针指向最后一个节点,则删除链表第一个节点
if (front.nextNode == null) {
front = linkList.head;
}
// 删除节点
front.nextNode = front.nextNode.nextNode;
// front.nextNode = this.nextNode(linkList, this.nextNode(linkList, front));
// front.nextNode会陷入死循环(front指向最后一个节点)
}
return linkList.head.nextNode.getInt();
}
/*
public Node nextNode(LinkList linkList, Node node) {
node = node.nextNode;
if (node == null) {
node = linkList.head.nextNode;
}
return node;
}
*/
}
class Start {
public static void main(String[] args) {
// 创建单链表
int[] arr = {10, 20, 30, 40, 50};
LinkList linkList = new LinkList(arr);
linkList.showAllNum();
//
Josephus_LinkList josephusLinkList = new Josephus_LinkList(linkList);
int survivor = josephusLinkList.getSurvivor(1, 3);
System.out.println(survivor);
}
}
运行结果: