1、单向环形链表思路
约瑟夫问题
构建:
1、先创建一个节点,让first指向该节点,并形成环形
2、后面当我们每创建一个新的节点,就把该节点,加入到已有的环形链表中即可
遍历:
1、先让辅助指针(变量)curBoy,指向first节点
2、然后通过一个while循环遍历该环形链表即可 curBoy.next==first 结束
比如:有五个人(n=5)
从第一个人开始报数(k=1)
数两下,数到二出圈(m=2)
出圈顺序:2->4->1->5->3
思路:
1、需求创建一个辅助指针(变量)helper,事先应该指向环形链表的最后这一个节点
2、报数前,先让first和helper 移动k-1次
3、报数时,first和helper指针同时移动m-1次
4、first指向就是要出圈的节点
first=first.next;
helper.next=first;
原来first指向的节点就没有任何引用,被回收
2、代码实现
package database;
public class Josefu {
public static void main(String[] args) {
CricleSingleLiked csl=new CricleSingleLiked();
csl.addBoy(5);
csl.showLiked();
csl.countBoy(1,2,5);
}
}
//创建一个环形单向链表
class CricleSingleLiked{
//创建一个节点
Boy first=null;
//添加小孩节点
public void addBoy(int nums){
//至少有一个小孩
if (nums<1){
return;
}
//最少需要两个小孩
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;
}
//添加后面节点,在第一个节点之后
else {
curBoy.setNext(boy);
boy.setNext(first);
curBoy=boy;
}
}
}
//遍历链表
public void showLiked(){
//判断是否为空
if (first==null){
System.out.println("链表为空");
return;
}
//不为空,且curboy==first
Boy curBoy=first;
while (true){
System.out.println("编号为"+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("输入有误,不在范围!");
return;
}
Boy helper=first;//代表循环结束
while (true){
if (helper.getNext()==first){
break;
}
helper=helper.getNext();
}
//先确定从第几个小孩开始报数,让指针指向小孩
for (int i = 0; i < startNo-1; i++) {
helper=helper.getNext();
first=first.getNext();
}
//每次数几下,让指针移动countnum-1次
while (true){
if (helper==first){
// System.out.println("只剩一个节点");
break;
}
for (int i = 0; i <countNum-1; i++) {
first = first.getNext();
helper=helper.getNext();
}
//first指向要出圈的小孩
System.out.println("出圈:"+first.getNo());
first = first.getNext();
helper.setNext(first);
}
System.out.println("最后一个节点是"+helper.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;
}
}