package linkedListDemo;
/**
* 模拟约瑟夫问题,就是模拟小孩出圈。
* 一圈小孩围一个环,然后数数,数到第m,这个小孩就出圈,然后从下一个小孩开始,重新数数,数到m再出来。
* 完成小孩出圈的顺序
*/
public class Josephu {
public static void main(String[] args) {
CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
circleSingleLinkedList.addBoy(5);
//circleSingleLinkedList.show();
circleSingleLinkedList.countBoy(1,2,5);
}
}
/*
创建一个小孩的单链表,里面提供小孩的添加操作和遍历操作
*/
class CircleSingleLinkedList{
/**
* 添加小孩的话,需要创建一个first,然后输入一个num代表添加多少个小孩进环形单链表
*/
private Boy first = null;
public void addBoy(int nums){
if(nums < 1){
System.out.println("添加的小孩数据有问题...");
return;
}
Boy curBoy = null;
for(int i = 1;i <= nums;i++){
//先把第一个节点有点特殊,处理了再说,让first指向它,然后next指到自己
Boy boy = new Boy(i);
if(i == 1){
first = boy;
first.setNext(first);
curBoy = first;
}else{
curBoy.setNext(boy);
boy.setNext(first);
curBoy = curBoy.getNext();
}
}
}
/*
分析:遍历唤醒链表的操作。只要curBoy.next == first就是遍历完成了
*/
public void show(){
if(first == null){
System.out.println("链表为空....");
return;
}
Boy curBoy = first;
while(true){
System.out.print(" "+curBoy.getNo()+" ");
if(curBoy.getNext() == first){
//链表走到头
break;
}
curBoy = curBoy.getNext();
}
}
/*
分析:约瑟夫问题实现
*/
/**
*
* @param startNum 开始从第几个小孩数数
* @param countNum 数到第几个小孩出队列
* @param nums 队列中一共有几个人
*/
public void countBoy(int startNum,int countNum,int nums){
if(first == null){
System.out.println("链表为空...");
return;
}
if(startNum < 1 || startNum > nums ){
System.out.println("输入的数据不合理...");
return;
}
Boy helper = first;
//将helper指向链表的最后一个节点
while(true){
if(helper.getNext() == first){
break;
}
helper = helper.getNext();
}
//将first和helper同时像后边移动countNum次
// k = 2;first只需要移动一次
for(int i = 0;i < startNum - 1;i++){
first = first.getNext();
helper = helper.getNext();
}
/*
计数countNum次,每一次到这个位置,就删除这个节点
*/
while(true){
if(helper == first){
break;
}
//k = 2;
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("最后一个留在链表中的小孩编号是:" + first.getNo());
}
}
/*
创建一个小孩的节点,包括编号和指针域
*/
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;
}
}
JAVA实现约瑟夫问题
最新推荐文章于 2023-03-31 01:30:35 发布