問題:數組
丟手帕遊戲是約瑟夫問題的一個變種,遊戲很簡單,N個小孩圍成一個圈,標號爲1到N,從編號爲m的小孩開始報數,報到第L個小孩退出遊戲,而後下一個小孩繼續從1開始報數,數到第L個小孩退出遊戲,如此循環,直到剩下最後一個小孩是勝利者.數據結構
使用環形鏈表方式解決問題:oop
代碼以下:ui
/** * 描述: * @做者:niexiaohui * @建立時間:2016年12月27日 * @修改記錄: */ public class Test { public static void main(String[] args) { long starttime=System.currentTimeMillis(); CircleLinkList game=new CircleLinkList(10000, 99, 533); long endtime=System.currentTimeMillis(); game.play(); long time2=System.currentTimeMillis(); System.out.println("建立鏈表用了"+(endtime-starttime)/1000.0+"秒"); System.out.println("玩遊戲共用了"+(time2-starttime)/1000.0+"秒"); } } class Child{ protected int no; protected Child nextChild; public Child(int no){ this.no=no; } } class CircleLinkList{ /** * 參與遊戲人數 */ private int playBoys; /** * 從第幾個開始數 */ private int startIndex; /** * 數幾個小孩退出 */ private int countNum; //首個小孩 private Child firstChild; //標識當前小孩 private Child temp; /** * * @param playBoys 參與遊戲人數 * @param startIndex 從第幾個開始數 * @param countNum 數幾個小孩退出 */ public CircleLinkList(int playBoys, int startIndex, int countNum) { super(); this.playBoys = playBoys; this.startIndex = startIndex; this.countNum = countNum; createList(); } /** * 建立循環鏈表 */ private void createList() { for (int i = 1; i <=playBoys; i++) { if (i==1) {//第一個小孩 Child child=new Child(i); this.firstChild=child; this.temp=child; }else if (i==playBoys) {//最後一個小孩 Child child=new Child(i); this.temp.nextChild=child; this.temp=child; this.temp.nextChild=this.firstChild;//最後一個小孩的下一個小孩指向第一個小孩 }else { Child child=new Child(i); this.temp.nextChild=child; this.temp=child; } } } /** * 玩遊戲 */ public void play(){ temp=firstChild; //先找到從第幾個小孩開始數 for (int i = 1; i < startIndex; i++) { temp=temp.nextChild; } System.out.println("遊戲開始,從第"+temp.no+"個小孩開始數,數到第"+this.countNum+"個小孩退出遊戲"); while (this.playBoys>1) { //找到要退出遊戲的前一個小孩 for (int i = 1; i < countNum-1; i++) { temp=temp.nextChild; } //當前temp是要退出的前一個小孩 Child leaveChild=temp.nextChild;//要退出的小孩 System.out.println("當前退出的小孩編號爲:" +leaveChild.no); temp.nextChild=leaveChild.nextChild; if (leaveChild.no==firstChild.no) {//若是要退出的小孩是第一個小孩,則將第一個小孩重置爲退出小孩的下一個小孩 this.firstChild=leaveChild.nextChild; } temp=temp.nextChild; this.playBoys--;//玩遊戲人數少一個 } System.out.println("最後剩下的小孩是:"+ temp.no); } }
代碼雖然很多,可是並不難懂,有過一點數據結構基礎的仍是很容易理解的.this
使用數組方式解決問題:spa
代碼以下:code
/** * 描述: * * @做者:niexiaohui * @建立時間:2017年1月11日 * @修改記錄: */ public class Test4 { public static void main(String[] args) throws InterruptedException { long starttime = System.currentTimeMillis(); int childrens=10000;//玩遊戲的小孩總數 int countNum=533;//數第幾個小孩退出遊戲 int startNum=99;//開始從第幾我的開始數 int count=1;//計數器 int [] arrays=new int[childrens]; for (int i = 0; i < arrays.length; i++) {//爲數組初始化值 arrays[i]=1; } loop:while(true){ for (int i = 0; i < arrays.length; i++) { if (i<startNum-1) {//第一次循環找到從第幾個小孩開始數數 continue; } startNum=0;//開始後將startNum清零 if (arrays[i]!=0) {//值爲0的表示已經退出遊戲 if (count%countNum==0) {//數到的小孩退出遊戲 if (childrens==1) { System.out.println("遊戲勝利的小孩編號爲:"+(i+1)); break loop; } arrays[i]=0;//退出遊戲的小孩值設爲0 count=0;//計數器清零,從新計數 childrens--;//玩遊戲的人數減一 System.out.println("編號爲"+(i+1)+"的小孩退出遊戲"); } count++; } } } long time2 = System.currentTimeMillis(); System.out.println("玩遊戲共用了" + (time2 - starttime)/1000.0 + "秒"); } }
用數組方式解決問題代碼少了不少,效率上,我大體比較了下,隨着數到第L個小孩退出遊戲,即L的增大,鏈表的速度會提高,相反數組會降低,若是L值很小的話,數組的效率是高於鏈表的效率的.blog