1.定义节点类
该节点类中只有孩子的编号,以及指向下一个节点的"指针"
package com.ebiz.list.josepfu;/*** @author YHj* @create 2019-07-17 22:21* 表示节点的类*/ public 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;}@Overridepublic String toString() {return "我是第" + no + "个Boy";}}
2.定义单向链表类
需要注意的是,josef问题是头尾相连的,在这也就是最后一个节点需要指向第一个节点,如果只有一个节点,那么该节点需要指向节点本身.
解决josef问题,关键是理解最后的josef方法.
package com.ebiz.list.josepfu;/*** @author YHj* @create 2019-07-17 22:16* 环形单项链表*/ public class SingleCircleList {//创建一个first 节点 没有编号也可以为空private Boy firstBoy =new Boy(-1);//添加节点,构成环形链表 需要注意的是第一个节点需要指向节点本身public void add(int num){if (num < 1 ){System.out.println("编号不正确");return;}//创建辅助节点Boy temp=null;//添加节点for (int i = 1; i <=num ; i++) {Boy boy = new Boy(i);if (i == 1){ //代表第一个节点firstBoy=boy;firstBoy.setNext(firstBoy);temp=firstBoy; //辅助接点}else {temp.setNext(boy);boy.setNext(firstBoy); //这里不能为temp 因为是环形链表,后面逐渐增加的节点的next应该是头节点temp=boy;}}}//遍历环形链表public void list( ){if (firstBoy.getNo() == -1){System.out.println("该环形链表为空!");return;}//定义辅助指针Boy temp=firstBoy;while (true){System.out.println(temp);if (temp.getNext().getNo() == 1){break;}temp=temp.getNext();}}/*josepfu问题的实现根据用户的输入,生成小孩出圈的顺序k:从哪里开始m:数几下num:玩游戏的小孩的数量*/public void josepfu(int k,int m,int num){//数据校验if (k>num || k<1 || m<1 || num<1){System.out.println("参数输入有误");}if(firstBoy.getNo() == -1){System.out.println("链表节点为空!");}//创建辅助指针 帮助小孩完成出圈Boy temp=firstBoy;//循环遍历,将该辅助指针指向最后一个,即firstBoy前一个while (true){if(temp.getNext() == firstBoy){break;}temp=temp.getNext();}// 报数之前.让first 和temp移动到对应位置 在k处报数,让first和temp移动k-1,// 移动到开始报数的孩子身上for (int i = 1; i <=k-1 ; i++) {firstBoy=firstBoy.getNext();temp=temp.getNext();}while (true){if (firstBoy == temp){break;}//开始报数,第k个孩子,即firstBoy当前指向的孩子//报m个数,,从第k个孩子本身报数,所以firstBoy移动m-1次,temp也移动m-1次for (int i = 1; i <=m-1 ; i++) {firstBoy=firstBoy.getNext();temp=temp.getNext();}//上面循环结束时,firstBoy指向要出去的孩子System.out.printf("小孩%d出圈",firstBoy.getNo());//这是将firstBoy指向将要出去的孩子的下一位,并且temp的next指向他firstBoy=firstBoy.getNext();temp.setNext(firstBoy);}System.out.printf("最后留在圈中的小孩编号%d",firstBoy.getNo()); //或者temp }}
3. 写一个简单测试类
package com.ebiz.list.josepfu;/*** @author YHj* @create 2019-07-18 9:30*/ public class Test {public static void main(String[] args) {//创建环形链表SingleCircleList circleList = new SingleCircleList();//环形链表添加节点circleList.add(5);//遍历链表 circleList.list();circleList.josepfu(1,2,5);} }
有不懂的欢迎留言评论!