问题介绍:
*又称丢手帕问题
*含编号的一组环形数组,从某一点开始遍历,每到第m个时数组元素出列
*求出列序号的队列
单向环形链表:
*最后一个元素节点指向第一个节点
*构建思路
1.创建第一个节点,使first指向该节点,并使其自身形成环形
2.当我们每创建一个新节点,将其加入环形链表中
3.添加过程
*创建一个last指针等于尾节点
*将last指针指向当前节点
*当前节点指向first节点
*last指针移动
*解决问题思路
1.创建一个辅助指针link,指向链表最后的节点
2.当报数时,将link与first同时移动m - 1次
3.这时将first指向节点输出
*输出当前first
*先将first后移
*然后将link.next = first
*代码总实现
*package 单向环形链表;
public class 约瑟夫问题 {
public static void main(String[] args) {
// TODO Auto-generated method stub
CircleSingleLinkedList circleSingle = new CircleSingleLinkedList();
circleSingle.addPeopleCircleList(5);
circleSingle.List();
circleSingle.Answer(2, 2, 5);
}
}
//创建链表
class CircleSingleLinkedList{
//创建first节点,暂不赋值
private PeopleCircleList first = null;
//添加节点,构建环形链表
public void addPeopleCircleList(int size){
//size数据检验
if(size < 1){
System.out.println("size error!");
return;
}
//创建last辅助节点
PeopleCircleList last = null;
for(int i = 1; i <= size; i++){
//根据编号创建节点
PeopleCircleList people = new PeopleCircleList(i);
if(i == 1){
first =people;
first.setNext(first); //构成环形
last = first; //辅助节点指向first
} else {
last.setNext(people);
people.setNext(first);
last = people;
}
}
}
//遍历链表
public void List(){
//判断是否为空
if(first == null){
System.out.println("没有数据");
return;
}
PeopleCircleList last = first;
while(true){
System.out.printf("输出编号为:%d \n",last.getNum());
if(last.getNext() == first){
break;
}
last = last.getNext();
}
}
//解决问题
public void Answer(int start,int size, int total){
//数据校验
if(first == null || start == 1 || start > total){
System.out.println("输入错误");
}
//创建临时节点
PeopleCircleList link = first;
while(true){
if(link.getNext() == first){
break;
}
link = link.getNext();
}
//移动至start
for(int i = 0; i < start - 1; i++){
first = first.getNext();
link = link.getNext();
}
while(true){
if(link == first){
//只有一个元素剩余
break;
}
for(int j = 0; j < size - 1; j++){
first = first.getNext();
link = link.getNext();
}
System.out.printf("输出编号为:%d \n",first.getNum());
first = first.getNext();
link.setNext(first);
}
System.out.printf("输出编号为:%d \n",first.getNum());
}
}
//创建节点
class PeopleCircleList{
private int num; //编号
private PeopleCircleList next; //指向下一个节点,默认为空
public PeopleCircleList (int num){
this.num = num;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public PeopleCircleList getNext() {
return next;
}
public void setNext(PeopleCircleList next) {
this.next = next;
}
}