构建单向的环形链表的思路:
1.先创建第一个节点,让first指向该节点,并形成环形
2.后面当我们每创建一个新的节点,就把该节点,加入到环形链表中即可
package linkedlist;
/*
* 约瑟夫环
* */
public class Josepfu {
public static void main(String[] args) {
CircleSingleLinkedList list = new CircleSingleLinkedList();
list.addBoy(5);
list.countBoy(2,3,5);
//list.showBoy();
System.out.println("--------------------------");
}
}
//创建一个环形的单向链表
class CircleSingleLinkedList{
//创建一个first节点,当前先没有编号
private Boy first = new Boy(-1);
//添加小孩节点,构成环形链表
public void addBoy(int nums){
//进行一个数据校验
if (nums < 1){
System.out.println("nums值不正确,nums值应该大于1");
}
Boy curBoy = null; //辅助指针,帮助构建环形链表
//用循环构建环形链表
for (int i = 1 ; i <= nums ; i++){
Boy boy = new Boy(i);//根据编号,构建小孩节点
if (i == 1){ //头结点
first = boy;
first.setNext(first); //构成环形节点
curBoy = first; //让curBoy指向first
}else{
curBoy.setNext(boy);
boy.setNext(first);
curBoy = boy;
}
}
}//添加小孩节点结束
//遍历环形链表
public void showBoy(){
//判断链表是否为空
if (first == null){
System.out.println("该链表为空!!!");
return;
}
Boy curBoy = first;//临时变量
while(true){
System.out.printf("当前小孩的编号为: %d\n",curBoy.getNo());
if (curBoy.getNext() == first){
break;
}
curBoy = curBoy.getNext();
}
}
//遍历环形链表结束
//根据用户输入,计算小孩出圈的顺序
/**
* @param startNo 表示从的几个孩子开始数
* @param countNum 表示数几下
* @param nums 表示最开始有几个小孩在圈内
* */
public void countBoy(int startNo,int countNum, int nums){
if (first == null || startNo < 1 || startNo > nums){
System.out.println("您输入的参数有误,请重新输入!");
}
//创建辅助指针,帮助完成小孩出圈
Boy helper = first;
//helper应事先指向最后一个节点
while(true){
if (helper.getNext() == first){
break;
}
helper = helper.getNext();
}
//小孩报数前,先让first和helper移动到报数的位置
for (int i=0; i < startNo-1; i++){
first = first.getNext();
helper = helper.getNext();
}
//报数,然后出圈,就是让指针移动m-1次
//当循环链表里面只有一个节点时,出圈结束
while (true){
if (first == helper){
break;
}
//移动到出圈的位置
for (int j=0;j<countNum-1;j++){
first = first.getNext();
helper = helper.getNext();
}
//让该节点出圈
System.out.printf("小孩 %d 出圈\n",first.getNo());
first = first.getNext();
helper.setNext(first);
}
System.out.println("最后留在圈中的小孩:"+first.getNo());
}//小孩出圈结束
}
//创建一个Boy类,表示一个节点
class Boy{
private int no; //编号
private Boy next;//指向下一个节点
//构造方法
public Boy(int no){
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
}
遍历环形链表
1.先让一个辅助指针curBoy,指向first节点
2.然后通过一个while循环遍历该环形链表即可。curBoy.next == first结束
版权声明:本文为weixin_45301190原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。