单向环形链表 joseph环问题
Joseph问题:n个小孩坐成一圈,编号为k的小孩从1开始报数,数到m的小孩出列,下一个小孩再从1开始报数,数到m出列,直到所有人出列为止,求出列的编号队列。
单向环形链表构建思路:
构建:
1) 先创建第一个节点,用first指向它,与自己形成环形队列。
2) 每创建一个新的节点,就把该节点加入到已有的环形列表中。
遍历:
1) 让辅助指针cur指向first
2) 通过while循环直到cur.next = first结束
约瑟夫问题:
1) 创建一个helper指针,指向first的前一个节点
2) 小孩报数前,移动k-1次helper和first
3) 开始数数,数m-1次,将first出列(first = first.next; helper.next = first),持续循环这个过程
4) 直到链表中剩余一个元素时退出循环(此时first = helper)
代码:
package com.dataStructure;
public class circleSingleLinkedList {
public static void main(String[] args){
CircleList circleList = new CircleList();
circleList.add(5);
circleList.show(circleList);
//测试
circleList.out(1,2,5);
}
}
class Boy{
private int value;
private Boy next;
public Boy(int value){
this.value = value;
}
public int getValue() {
return value;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
public void setValue(int value) {
this.value = value;
}
}
class CircleList{
Boy first = null;
Boy cur = null;
public void add(int size){
if(size<1){
return;
}else{
for(int i = 1;i<=size;i++){
Boy newBoy = new Boy(i);
if (i == 1){
first = newBoy;
newBoy.setNext(first);
cur = newBoy;
}else{
cur.setNext(newBoy);
newBoy.setNext(first);
cur = cur.getNext();
}
}
}
}
public void show(CircleList list){
if (list.first == null){
System.out.println("小孩都被吃光了!!!");
return;
}
if(list.first.getNext() == list.first)
{
System.out.printf("只有一个小孩%d",list.first.getValue());
}else{
Boy temp = list.first;
while(true){
System.out.printf("第%d个小孩",temp.getValue());
System.out.println();
if (temp.getNext() == list.first){
break;
}
temp = temp.getNext();
}
}
}
public void out(int startNo, int count, int nums){ //startno:开始的序号 count:数几下 nums:总数
if(startNo>nums || startNo < 1 || first == null){
return;
}
//让helper到达初始位置
Boy helper = first;
while(true){
helper = helper.getNext();
if (helper.getNext() == first){break;};
}
//让first和helper找到开始数数的位置
for(int i = 0; i < startNo-1; i++){
helper = helper.getNext();
first = first.getNext();
}
//开始数数,并且排除掉要拍出的数字,最终留下一个在链表中
while(true){
if (first == helper){
break;
}
for (int j = 0; j < count-1; j++){
helper = helper.getNext();
first = first.getNext();
}
System.out.print(first.getValue()+" -> ");
first = first.getNext();
helper.setNext(first);
}
System.out.print(first.getValue());
}
}