問題ジョセフを解決するためにJavaのサイクル単独リンクリストを使用します

問題ジョセフは何ですか

有名なユダヤ人の歴史家ヨセフスは、次の物語を持っていたと言われて:Qiaotapate、39人のユダヤ人とヨセフスと彼の友人が洞窟に隠れ、ローマ占領した後、39人のユダヤ人は、むしろ死んでしまう決めて、敵を巻き込まないでくださいそして自殺、円形に配置された41人の個人、最初の個人的なCountinを決め、すべての3番目の数字は、すべての自殺まで、新聞による再カウント、その後、自殺を持っている人に報告しましたこれまでに死亡しました。しかし、ヨセフスと彼の友人は従わたくありませんでした。個々のk-2(最初の男が逆になっているため)を超えて、人と起動し、k個の個人を殺します。次に、K-1、次いで、個々の上、及びk番目の個体を殺します。最終的には唯一の次の人は残すようになるまでのプロセスは、円の周り続けて、この人は生き続けることができます。問題は、与えられたと、実行を避けるために、どこかに立って始めて、ということでしょうか?

ヨセフの物語残酷比較し、以下のように、私たちは少しゲームを変えたヨセフの問題は、ゲームのルールは以下のとおりです。

  手の円を手に、番号1,2,3 ... n個の個別のリビングを想定、パケット数の合意された数k(1 <= K <= N)彼の、m個のターンのうち人の数、始まりました1と下部オフ番号、からm個の環のうちの人々の数など、残りの1つは、それにより円のシーケンス番号を生成し、勝者になるまで、

アナログの周りに座って、n個の個人を使用して循環リスト

まず、我々はそれによって、n個の円に座って個人をシミュレートし、循環リンクリストを定義します。以下の単鎖実装コードの下に見て

1  / * 
2  *一方向循環リスト
 3。  * / 
4。 クラスCycleSingleLinkedList {
 5。      PersonalNodeまず= NULL ;
 6      / ** 
。7       * NUM循環リストにノードを追加します
 。8       * @paramのNUM
 。9       * / 
10      公共 ボイド追加(INT NUM){
 11。         IF(NUM <1。){
 12は              System.out.printf( "無効なパラメータ" );
 13である             返す;
 14          }
 15          PersonalNode CURR = NULL;
16          のためには、int型 1 = Iを、I <= NUM; iは++ ){
 17              PersonalNode personalNode = 新しいPersonalNode(I)。
18              もし(I == 1 ){
 19                  // 添加第一个节点
20                  第= personalNode。
21                  CURR = 最初;
22                  curr.setNext(最初の);
23              } {
 24                  curr.setNext(personalNode)。
25                  (第一)personalNode.setNext。
26                  CURR = personalNode;
27             }
28         }
29 
30     }
31 
32 }
33 
34 /**
35  * 人物节点
36  */
37 class PersonalNode {
38     private int no;
39     private PersonalNode next;
40 
41     public PersonalNode(int no){
42         this.no = no;
43     }
44 
45     public int getNo() {
46         return番号;
47      }
 48  
49      公共 ボイド(setNo INT なし){
 50          この .NO = いいえ。
51      }
 52  
53      公衆PersonalNode getNextを(){
 54          リターン次。
55      }
 56  
57      公共 ボイドsetNext(PersonalNode次){
 58          この .next = 次回。
59      }
 60 }

我々は最初のノードを作成するときにプロセスの凡例は円形のリストをn個のノードを追加する方法を説明下に形成するために、我々は、第1のノードと次電流に第1ノード点に第一及び現在のポイントを聞かせてループ。第2のノードを追加する場合、次のように最初に第2のノード次に、第二の電流ノードへのポインタであり、そして第2のノードへの電流、すなわち、現在のポイントを移動します。

 

今では私たちの問題解決のn kの第二段階から次の番号を達成するために、一緒に座って個人が少数の個人を始めた最初のステップです。第二のステップは、K-1回、人々の数の最初の数を作ることにより、最初のポインタように、すなわち第一のポインタが移動され、比較的簡単です。しかし、ノードのうち最初のラップには円形のリストであるため、次のポインタは、第1のヘルパー(に等しくなるまで、我々はそのようにサイクルを最初にヘルパーポインタポイントせまず、すなわち、ノードの前に第一のポインタをポイントするようにヘルパー・ポインタを定義し、必要性を指摘)。そして、常に最初のノードのポインタ(最初のノードと同じノードへのポインタ)の前にヘルパーポインタを保持します。即ち、K = 2を想定している第二の個体から始まるの数、M = 3、すなわち、図に示すようにリング3のうち人の数、。

 

この時点で第一次ヘルパー次に等しくなるように、円をノード4、その後、図3に示すように、第一次のヘルパーが等しいせ人を見つけます。

 

ノード1は、開始番号、番号3、すなわちノード3円、図のケースへのポインタとして、この時点から継続します。

次の環の環をノード3の後にノード1であり、そして第1のヘルパーへのポインタと同じノード、すなわち、ノード2までのサイクルは、円への最後のものです。コードは以下の通りです

 1 /**
 2      * 约瑟夫问题
 3      * @param n n个人围成圈
 4      * @param k 第k个人开始报数
 5      * @param m 数到m的人出圈
 6      */
 7     public void joseph(int n,int k,int m){
 8         //添加n个人
 9         add(n);
10         //helper指针指向first的前一个节点
11         PersonalNode helper = first;
12         while (helper.getNext() != first){
13             helper = helper.getNext();
14         }
15         //找到第k个人
16         for (int i = 0; i < (k-1); i++) {
17             first = first.getNext();
18             helper = helper.getNext();
19         }
20         //数到m的人出圈
21         while (true){
22             if(helper == first){
23                 break;
24             }
25             for (int i = 0; i < (m-1); i++) {
26                 first = first.getNext();
27                 helper = helper.getNext();
28             }
29             System.out.printf("编号为%d的人出圈\n",first.getNo());
30             first = first.getNext();
31             helper.setNext(first);
32         }
33         System.out.println("最后出圈的人是:"+first.getNo());
34 
35     }

测试代码

1 public static void main(String []args){
2         CycleSingleLinkedList linkedList = new CycleSingleLinkedList();
3         linkedList.joseph(4,2,3);
4 }

测试结果:

 

 

总结

以上就是实现约瑟夫问题的循环链表解决思路,当然肯定还有很多别的解决思路,欢迎留言探讨,谢谢。

おすすめ

転載: www.cnblogs.com/menglong1108/p/11617542.html