最近比較有時間啦,有時間搞下java,個人覺得學這門語言語法太多啦,不一一去學習啦,心血來潮,掛了個struct2的源代碼,一入深似海啊,看得我天花繚亂,從最簡單的開始吧。
約瑟夫問題,也是被稱為丟手絹問題。利用C 或Java的單向環形鍊錶能夠較好的解決,但絕對不是最簡單的方法。就只是我在學習Java的過程中的一個小小的作業題。
問題的來源,據說著名猶太歷史學家Josephus有過以下的故事:在羅馬人佔領喬塔帕特後,39 個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了一個自殺方式,41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下一個重新報數,直到所有人都自殺身亡為止。然而Josephus 和他的朋友並不想遵從。首先從一個人開始,越過k-2個人(因為第一個人已經被越過),並殺掉第k個人。接著,再越過k-1個人,並殺掉第k個人。這個過程沿著圓圈一直進行,直到最終只剩下一個人留下,這個人就可以繼續活著。問題是,一開始要站在什麼地方才能避免被處死? Josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,於是逃過了這場死亡遊戲。
具體的要求請參考度娘:約瑟夫問題
public class Demo4 { public static void main(String[] args) { // TODO Auto-generated method stub CycLink cyclink = new CycLink(); int len=41; int k=1; int m=3; cyclink.setLen(len); cyclink.creatLink(); cyclink.show(); cyclink.setK(k); cyclink.setM(m); cyclink.playgame(); } } class Node { int no; Node nextNode = null; //节点的构造函数 public Node(int no) { //给一个编号 this.no = no; } } //环形链表 class CycLink { //先定义一个指向链表第一个节点的引用 //指向第一个节点的引用不能动 Node firstNode = null;//没有新开辟空间,它在纸上谈兵!!!! Node tempNode =null;//跑龙套的选手!!!很重要!!!!(纸上谈兵) int len = 0;//表示共有多少个节点(Node) int k =0;//表示要从第k个节点开始计数 int m =0;//表示每数到m个节点要被删除 //设置链表的大小(长度) public void setLen(int len) { this.len = len; } //设置从第k个人开始计数 public void setK(int k) { this.k=k; } //设置从第m个人开始计数 public void setM(int m) { this.m=m; } //初始化环形链表 public void creatLink() { for(int i=1;i<= len ;i++) { if(i==1) { //创建第一个节点 Node ch=new Node(i);//ch可不是纸上谈兵,实实在在的开辟了空间 this.firstNode = ch;//“纸上”的firstNode指向了有实际空间的ch this.tempNode = ch;//“纸上”的tempNode指向了有实际空间的ch } else //其余节点(不是第一个头结点) { if(i==len)//(如果要创建最后一个节点) { //创建最后一个节点 Node ch=new Node(i);//创建(实际开辟)最后节点,以第二个为例 tempNode.nextNode = ch;//"纸上"的tempNode.nextNode指向2节点 tempNode = ch;//在“纸上”变更龙套选手 tempNode.nextNode = this.firstNode;//纯粹纸上谈兵,龙套(最后节点)的下个节点指回初始节点 } else { //继续创建一个节点 Node ch=new Node(i);//创建(实际开辟)下一个节点,以第二个为例 tempNode.nextNode = ch;//"纸上"的tempNode.nextNode指向2节点 tempNode = ch;//在“纸上”变更龙套选手 } } } } //开始丢手帕游戏 public void playgame() { //1、找到第k个节点 Node temp1=null; Node temp2=null; temp1 = firstNode; for(int i=1; i<k; i++) { temp1=temp1.nextNode; } int cn=1;//删除的顺序标志 while(len!=1) { //2、从第1步中找到的k人开始计数,找第m-1个用户(方便第3步修改其下个节点的指向) for(int j=1; j<m-1; j++) { temp1=temp1.nextNode; } //3、将第2步中找到的用户修改其下个节点的指向 temp2=temp1.nextNode;//temp2就是要被删去的节点 System.out.println("第"+cn+"个删除的节点编号:"+ temp2.no); temp1.nextNode=temp2.nextNode; temp1 = temp1.nextNode; cn++; len--; } //4、显示最后剩下的节点 System.out.println("最后剩下的节点是:"+temp1.no); } //打印该循环链表 public void show() { //定义个龙套选手 Node temp=this.firstNode;//将“龙套”选手的“帽子”扣在第一个节点上 System.out.print("初始节点编号: "); do { System.out.print(temp.no+" "); temp = temp.nextNode; }while(temp!=this.firstNode); System.out.println(" "); } }
相關推薦:
PHP-Java-Bridge使用筆記,php-java-bridge
#java學習隨筆--- 搗蛋vector,java隨筆---vector
以上是經典問題約瑟夫問題的Java實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!