分析:
比如由5个节点组成一个环,从第1个节点开始报数,每报数2个节点删除一个节点,单链表如下:
(1)设置一个helper辅助节点,指向最后一个节点:
(2)因为是从第k个节点开始报数,因此先让first和helper走k-1步,这样first节点就指向报数的第一个节点了,k初始值为1,因此不用向前走
(3)然后开始删除节点,每次让helper和first向前走1步,走了m-1步支行,first指向一个要删除的节点,第一个要删除的节点如下:
(4)让first=first.next,helper.next=first,则第2个节点删除:
(5)重复第4和第5步,直到helper等于first时,证明只有最后一个节点
(6)删除最后一个节点
实现:
public class Josepfu {
public static void main(String[] args) {
CircleSingleLinkedList list = new CircleSingleLinkedList();
for(int i = 1 ; i <= 5; i++) {
list.add(i);
}
list.print();
list.josepfu(1,2);
}
}
class CircleSingleLinkedList{
private Node first = null;
public void add(int num) {
Node node = new Node(num);
if(null == first) {
first = node;
node.next = first;
}else{
Node temp = first;
//找到最后一个节点
while(temp.next != first) {
temp = temp.next;
}
temp.next = node;
node.next = first;
}
}
public void print() {
if(null == first) {
return;
}
Node temp = first;
while(temp.next != first) {
System.out.print(temp.num);
System.out.print(" ");
temp = temp.next;
}
System.out.print(temp.num);
System.out.print(" ");
System.out.println("\n---------------");
}
//从第k个节点报数,报数m次删除一个节点
public void josepfu(int k, int m) {
if(null == first || m <= 0) {
return;
}
Node helper = first; //辅助节点
//先让辅助节点指向最后一个节点
while(helper.next != first) {
helper = helper.next;
}
//让helper和first节点向前走k-1次
for(int i = 1; i < k; i++) {
helper = helper.next;
first = first.next;
}
//当helper等于first的时候,只剩下一个节点
while(helper != first) {
int temp = m - 1;
while(temp-- != 0) {
helper = helper.next;
first = first.next;
}
System.out.println(first.num);
first = first.next;
helper.next = first;
}
System.out.println(first.num);
}
}
//节点定义
class Node{
public int num;
public Node next;
public Node(int num) {
this.num = num;
}
}
结果: