数据结构 - 链表(单向环形链表)(约瑟夫问题)
生活随笔
收集整理的這篇文章主要介紹了
数据结构 - 链表(单向环形链表)(约瑟夫问题)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
問題如下(與分析)
構建思路
輸入一個數(shù),數(shù)到這個數(shù)的小孩出圈,出圈順序的思路
代碼實現(xiàn)
根據(jù)圖解,來一步一步實現(xiàn)
//根據(jù)用戶輸入,計算小孩出圈順序/**** @param startNo 表示從第幾個小孩開始數(shù)數(shù)* @param countNum 表示數(shù)幾下出圈* @param nums 表示最初有多少小孩在圈中*/public void countBoy(int startNo, int countNum, int nums){//先對數(shù)據(jù)校驗if (first == null || startNo<1 || startNo > nums){System.out.println("輸入有誤,重新輸入");return;}//創(chuàng)建輔助指針,幫助出圈Boy helper = first;while (true){if (helper.getNext() == first){ //說明helper指向最后小孩節(jié)點break;}helper = helper.getNext();}//小孩報數(shù)前,先讓first 和 helper 移動 k - 1 次for (int j = 0; j < startNo -1; j++){first = first.getNext();helper = helper.getNext();}//當小孩報數(shù)時,讓first 和 helper 指針同時 移動 m - 1 次,然后出圈//這里是一個循環(huán)操作,直到圈中只有一個小孩while (true){if (helper == first){ //說明只有一個節(jié)點break;}//讓first 和 helper 同時移動 countNum - 1for (int i = 0; i < countNum -1; i++){first = first.getNext();helper = helper.getNext();}//這時first指向的節(jié)點,就是要出圈的節(jié)點System.out.printf("小孩 %d 出圈\n",first.getNo());//出圈(刪除first指向的節(jié)點)first = first.getNext();helper.setNext(first);}System.out.println("最后留在圈中的小孩編號:"+first.getNo());} }測試
CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();circleSingleLinkedList.addBoy(5); //加入五個小孩節(jié)點//測試小孩出圈 circleSingleLinkedList.countBoy(1,2,5);結果: 小孩 2 出圈 小孩 4 出圈 小孩 1 出圈 小孩 5 出圈 最后留在圈中的小孩編號:3完整代碼
package DataStructures.LinkedList;/*** 約瑟夫問題*/ public class Josepfu {public static void main(String []args){CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();circleSingleLinkedList.addBoy(5); //加入五個小孩節(jié)點//遍歷//circleSingleLinkedList.showBoy();//測試小孩出圈circleSingleLinkedList.countBoy(1,2,5);} } //創(chuàng)建一個環(huán)形單向鏈表 class CircleSingleLinkedList{//創(chuàng)建一個first節(jié)點,當前沒有編號private Boy first = null;//遍歷環(huán)形鏈表public void showBoy(){//先判斷是否為空if (first == null){System.out.println("鏈表為空");return;}//因為first不能動,要用輔助指針完成遍歷Boy cur = first;while (true){System.out.printf("小孩的編號是:%d \n",cur.getNo());if (cur.getNext() == first){ //遍歷完break;}cur = cur.getNext(); //后移}}//添加小孩節(jié)點,構建環(huán)形鏈表public void addBoy(int nums){//驗證numsif (nums<1){System.out.println("nums的值不正確");return;}Boy cur = null; //輔助指針幫助構建環(huán)形鏈表//使用for來構建環(huán)形鏈表for (int i = 1; i <= nums; i++){//根據(jù)編號創(chuàng)建小孩節(jié)點Boy boy = new Boy(i);//如果是第一個小孩if (i == 1){first = boy;first.setNext(first); //構成一個環(huán)cur = first; //讓cur指向第一個小孩,first不能動} else {cur.setNext(boy);boy.setNext(first);cur = boy;}}}//根據(jù)用戶輸入,計算小孩出圈順序/**** @param startNo 表示從第幾個小孩開始數(shù)數(shù)* @param countNum 表示數(shù)幾下出圈* @param nums 表示最初有多少小孩在圈中*/public void countBoy(int startNo, int countNum, int nums){//先對數(shù)據(jù)校驗if (first == null || startNo<1 || startNo > nums){System.out.println("輸入有誤,重新輸入");return;}//創(chuàng)建輔助指針,幫助出圈Boy helper = first;while (true){if (helper.getNext() == first){ //說明helper指向最后小孩節(jié)點break;}helper = helper.getNext();}//小孩報數(shù)前,先讓first 和 helper 移動 k - 1 次for (int j = 0; j < startNo -1; j++){first = first.getNext();helper = helper.getNext();}//當小孩報數(shù)時,讓first 和 helper 指針同時 移動 m - 1 次,然后出圈//這里是一個循環(huán)操作,直到圈中只有一個小孩while (true){if (helper == first){ //說明只有一個節(jié)點break;}//讓first 和 helper 同時移動 countNum - 1for (int i = 0; i < countNum -1; i++){first = first.getNext();helper = helper.getNext();}//這時first指向的節(jié)點,就是要出圈的節(jié)點System.out.printf("小孩 %d 出圈\n",first.getNo());//出圈(刪除first指向的節(jié)點)first = first.getNext();helper.setNext(first);}System.out.println("最后留在圈中的小孩編號:"+first.getNo());} } //先創(chuàng)建一個Boy類,表示一個節(jié)點 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;} }總結
以上是生活随笔為你收集整理的数据结构 - 链表(单向环形链表)(约瑟夫问题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《EVA新剧场版》主题高跟鞋:优雅华丽更
- 下一篇: 可转债值得投资吗?可转债的最大的风险是什