1. 節點構建
//構建節點
class Item{
private int no;
private Item next;
public Item(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public Item getNext() {
return next;
}
public void setNext(Item next) {
this.next = next;
}
@Override
public String toString() {
return "item [no=" + no + "]";
}
}
2、約瑟夫鏈表構建
- 代碼
//構建josephu鏈表
class JosephuLinkList{
//創建first指針,用於指向第一個節點
Item first = null;
//添加nums個節點
public void add(int nums) {
//對nums進行校驗
if(nums < 1) {
System.out.println("添加個數不正確!");
}else {
//輔助指針,用於指向當前的節點
Item curItem = null;
for (int i = 1; i <= nums; i++) {
Item item = new Item(i);
if(i == 1) {//第一次添加
first = item;
item.setNext(item);
curItem = item;
}else {
curItem.setNext(item);
item.setNext(first);
curItem = item;
}
}
}
}
//遍歷
public void list() {
if(first == null) {
System.out.println("尚無節點!");
return;
}
Item curItem = first;
while (true) {
System.out.printf("打印環裝鏈表數據:item的no:%d\n",curItem.getNo());
if(curItem.getNext() == first) {
break;
}else {
curItem = curItem.getNext();
}
}
}
/**
*
* @param startItem 第幾個開始
* @param count 樹幾下
* @param nums 一共幾個人
*/
public void countItems(int startItem,int count,int nums ) {
//首先對數字進行校驗
if(startItem < 1||startItem > nums||nums < 1) {
System.out.println("輸入格式不正確!");
return;
}
//定義輔助變量,指向環狀鏈表尾部
Item helper = first;
while(true) {
if(helper.getNext() == first) {
break;
}
helper = helper.getNext();
}
//第幾個開始 firse和helper 一起移動(startItem-1)下
for(int i = 0; i < startItem-1; i++) {
first = first.getNext();
helper = helper.getNext();
}
//開始循環數數並打印
while(true) {
if(first == helper) {
break;
}
//數count下 firse和helper 一起移動(count-1)下
for(int i = 0; i < count-1; i++) {
first = first.getNext();
helper = helper.getNext();
}
//打印節點數據並刪除節點
System.out.printf("josephu打印數據:%d\n",first.getNo());
//並刪除節點
first = first.getNext();
helper.setNext(first);
}
//打印最後一個節點
System.out.printf("josephu打印數據:%d\n",first.getNo());
}
}
- 思路
1、首先定義輸入參數:一共幾個同學nums,從第幾個開始startItem,每次數幾下count;
2、定義輔助變量/指針:helper指向尾部,即first指針的前一個節點,作用:用於刪除節點(helper指向待刪除節點的前一個節點)
3、先讓helper和firse指針同時移動(startItem-1)下,到開始同學的位置。
4、開始玩遊戲,讓同學數count下,同時first和helper指針移動(count-1)下,然後打印first指針指向節點的信息,然後刪除first指針指向的節點:
first = first.next;
helper.next = first;
5、first指向的同學繼續玩遊戲,重複第四步驟,直到剩下最後一個同學。
3. 測試
- 代碼:
public class JosephuLinkListDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
JosephuLinkList josephuLinkList = new JosephuLinkList();
josephuLinkList.add(15);
josephuLinkList.list();
josephuLinkList.countItems(1,2,15);
}
}
- 測試結果:
打印環裝鏈表數據:item的no:1
打印環裝鏈表數據:item的no:2
打印環裝鏈表數據:item的no:3
打印環裝鏈表數據:item的no:4
打印環裝鏈表數據:item的no:5
打印環裝鏈表數據:item的no:6
打印環裝鏈表數據:item的no:7
打印環裝鏈表數據:item的no:8
打印環裝鏈表數據:item的no:9
打印環裝鏈表數據:item的no:10
打印環裝鏈表數據:item的no:11
打印環裝鏈表數據:item的no:12
打印環裝鏈表數據:item的no:13
打印環裝鏈表數據:item的no:14
打印環裝鏈表數據:item的no:15
josephu打印數據:2
josephu打印數據:4
josephu打印數據:6
josephu打印數據:8
josephu打印數據:10
josephu打印數據:12
josephu打印數據:14
josephu打印數據:1
josephu打印數據:5
josephu打印數據:9
josephu打印數據:13
josephu打印數據:3
josephu打印數據:11
josephu打印數據:7
josephu打印數據:15