循環鏈解決約瑟夫問題
詳細解釋,請見代碼註釋
package linkedList;
public class CircleLinkedListDemo
{
public static void main(String[] args)
{
CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
circleSingleLinkedList.addBoy(25);
circleSingleLinkedList.show();
circleSingleLinkedList.countBoy(1, 2, 25);
}
}
//創建一個單向鏈表
class CircleSingleLinkedList
{
//創建一個first節點,當前沒有編號
private Boy first = null;
//添加一個小孩節點,構建成一個環形的鏈表
public void addBoy(int nums)
{
if(nums < 1)
{
System.out.println("nums的值不正確~");
return;
}
Boy curBoy = null;
//使用for來創建我們的環形鏈表
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 show()
{
if(first == null)
{
System.out.println("鏈表爲空~");
return;
}
else
{
Boy curBoy = first;
while(true)
{
System.out.println("小孩的編號 : " + curBoy.getNo());
//說明已經遍歷完畢
if(curBoy.getNext() == first)
{
break;
}
curBoy = curBoy.getNext(); //curBoy後移
}
}
}
//約瑟夫環算法
public void countBoy(int startNo, int countNum, int nums)
{
//先對數據進行校驗
if(first == null || startNo < 1 || startNo > nums)
{
System.out.println("參數輸入有誤,請重新輸入~");
return;
}
//創建輔助指針,幫助完成小孩出圈
Boy helper = first;
//需要一個輔助指針(變量)helper,事先應該指向環形鏈表的最後一個節點
while(true)
{
if(helper.getNext() == first) {
break;
}
helper = helper.getNext();
}
//小孩報數之前,先讓first和helper移動startNo-1次
for(int j=0;j<startNo-1;j++)
{
first = first.getNext();
helper = helper.getNext();
}
//當小孩報數時,讓first和helper指針同時後移m-1次,然後出圈
//這裏是一個循環操作,直到圈中只有一個節點
while(true)
{
if(helper == first) //圈中只剩一個節點
{
break;
}
//first、helper後移countNum-1次
for(int j=0;j<countNum-1;j++)
{
first = first.getNext();
helper = helper.getNext();
}
//這時first指向的節點,即出圈的節點
System.out.printf("小孩%d出圈\n", first.getNo());
//first指針後移
first = first.getNext();
helper.setNext(first);
}
System.out.println("最後留在圈中的小孩編號: " + first.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;
}
}