/*
* 问题原型
*/
41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。约瑟夫将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
/*
* 问题分析
*/
这个问题还有一种描述为丢手绢问题,因此代码命名以shoujuan
由于最近在学习java,因此决定用java链表来完成这个问题。设计一个循环链表,将41个人链接起来,选定一个人作为起始,逢3进行remove动作。
需要设计类:
shoujuan,用以表示每个人。包含成员:number用以计数,nextJuan用以表示下一个人。
ShouJuanList,用以表示链表。包含成员:shouJuanFirst用以表示第一个人,shouJuanNbr用以表示总人数。包含方法:makeCircle()制造环形链表,addShouJuan()新增一个节点,removeShouJuan()删除一个节点。
/*
* 难点分析
*/
在完成这个代码的过程中,主要考虑到循环链表的特性,即最后一个又指向头结点。完成这个代码需要对传值和传址有十分清晰的认识,传入的地址是会影响这个地址上是值的。
需要对头结点、第二个结点做特殊的考虑,防止有遗漏情况。
方法不是最简的,作为学习途中的一个标记,mark一下。
/*
* 代码
*/
ShouJuan.java
1 package com.diushoujuan; 2 3 public class ShouJuan { 4 private int number; 5 private ShouJuan nextJuan = null; 6 7 public ShouJuan(int n){ 8 this.number = n; 9 } 10 11 public int getNumber() { 12 return number; 13 } 14 15 public void setNumber(int number) { 16 this.number = number; 17 } 18 19 public ShouJuan getNextJuan() { 20 return nextJuan; 21 } 22 23 public void setNextJuan(ShouJuan nextJuan) { 24 this.nextJuan = nextJuan; 25 } 26 27 public void showNbr(){ 28 System.out.println("nub is: "+ this.number); 29 } 30 }
ShouJuanList.java
1 package com.diushoujuan; 2 3 /* 4 * 创建循环链表 5 */ 6 public class ShouJuanList { 7 private ShouJuan shouJuanFirst = null; 8 9 private int shouJuanNbr = 0; 10 11 public int getShouJuanNbr() { 12 return shouJuanNbr; 13 } 14 15 public void setShouJuanNbr(int shouJuanNbr) { 16 this.shouJuanNbr = shouJuanNbr; 17 } 18 19 public ShouJuan getShouJuanFirst() { 20 return shouJuanFirst; 21 } 22 23 public void setShouJuanFirst(ShouJuan shouJuanFirst) { 24 this.shouJuanFirst = shouJuanFirst; 25 } 26 27 //制造环形链表 28 public void makeCircle(){ 29 if(shouJuanFirst != null){ 30 ShouJuan shouJuanTemp = shouJuanFirst; 31 while(null != shouJuanTemp.getNextJuan()){ 32 shouJuanTemp = shouJuanTemp.getNextJuan(); 33 } 34 shouJuanTemp.setNextJuan(shouJuanFirst); 35 } 36 } 37 38 //新增一个节点 39 public void addShouJuan(ShouJuan shouJuan){ 40 ShouJuan shouJuanTemp = null; 41 if(shouJuanFirst == null){ 42 shouJuanFirst = shouJuan; 43 }else{ 44 shouJuanTemp = shouJuanFirst; 45 while(null != shouJuanTemp.getNextJuan()){ 46 shouJuanTemp = shouJuanTemp.getNextJuan(); 47 } 48 shouJuanTemp.setNextJuan(shouJuan); 49 } 50 shouJuanNbr++; 51 } 52 53 //删除一个节点 54 public void removeShouJuan(ShouJuan shouJuan){ 55 ShouJuan shouJuanTemp = shouJuanFirst; 56 if (shouJuanTemp == shouJuanFirst && shouJuanTemp.getNumber() == shouJuan.getNumber() && shouJuanNbr == 1) { 57 shouJuanFirst = null; 58 shouJuanNbr--; 59 }else if(shouJuanTemp == shouJuanFirst && shouJuanTemp.getNumber() == shouJuan.getNumber() && shouJuanNbr == 2){ 60 shouJuanFirst = shouJuanFirst.getNextJuan(); 61 shouJuanNbr--; 62 }else if(shouJuanTemp == shouJuanFirst && shouJuanTemp.getNumber() == shouJuan.getNumber() && shouJuanNbr>2){ 63 while(shouJuanTemp.getNextJuan() != shouJuanFirst){ 64 shouJuanTemp = shouJuanTemp.getNextJuan(); 65 } 66 shouJuanTemp.setNextJuan(shouJuanFirst.getNextJuan()); 67 shouJuanFirst = shouJuanFirst.getNextJuan(); 68 shouJuanNbr--; 69 }else{ 70 if(shouJuanTemp == shouJuanFirst && shouJuanTemp.getNumber() != shouJuan.getNumber()){ 71 shouJuanTemp = shouJuanTemp.getNextJuan(); 72 } 73 while(true){ 74 if(shouJuanTemp.getNextJuan().getNumber() == shouJuan.getNumber()){ 75 shouJuanTemp.setNextJuan(shouJuanTemp.getNextJuan().getNextJuan()); 76 shouJuanNbr--; 77 break; 78 } 79 shouJuanTemp = shouJuanTemp.getNextJuan(); 80 } 81 } 82 } 83 }
PlayGame.java
package com.diushoujuan; public class PlayGame { public final static int shouJuanNbr = 2; public final static int shouJuanRemoveNbr = 2; public static void main(String[] args) { ShouJuanList shouJuanList = new ShouJuanList(); for(int i = 1; i<=shouJuanNbr; i++){ ShouJuan shouJuan = new ShouJuan(i); shouJuanList.addShouJuan(shouJuan); } shouJuanList.makeCircle(); ShouJuan shouJuanRemove = shouJuanList.getShouJuanFirst(); while(shouJuanList.getShouJuanNbr() >= shouJuanRemoveNbr){ if (shouJuanRemove != shouJuanList.getShouJuanFirst()) { shouJuanRemove= shouJuanRemove.getNextJuan(); } for(int i = 1;i< shouJuanRemoveNbr;i++){ shouJuanRemove = shouJuanRemove.getNextJuan(); } shouJuanList.removeShouJuan(shouJuanRemove); } ShouJuan shouJuanShow = shouJuanList.getShouJuanFirst(); for(int i = 1;i< shouJuanRemoveNbr;i++){ shouJuanShow.showNbr(); shouJuanShow = shouJuanShow.getNextJuan(); } } }
时间: 2024-10-11 22:29:08