Josephus問題解決方法三(單向迴圈連結串列標識法)

Diy_os發表於2015-12-02
前面解決Josephus問題時(http://blog.itpub.net/29876893/viewspace-1815055/http://blog.itpub.net/29876893/viewspace-1850077/),都是找到該同學後,把該同學從環中除去,然後剩下的同學再組成一個新的環,終止條件是p != p->next。下面我們換種方式考慮該問題,可不可以找到該同學後,標識該同學,然後一直迴圈該環,直到把所有的人都標識,終止迴圈的條件是標識位等於環中的人數(flag=length),最後"標識"的同學就是獲勝者。我把這種方法叫做,“單向迴圈連結串列標識法”,下面給出程式碼:

點選(此處)摺疊或開啟

  1. #include<iostream>
  2. using namespace std;
  3. typedef struct Note{
  4.     char ch;
  5.     struct Note *next;
  6. }*node;

  7. int length;
  8. int flag;

  9. void initNote(node first) {
  10.     first = new Note;
  11.     first->next = NULL;
  12. }

  13. void createNote(node first) {
  14.     node p, q;
  15.     p = first;
  16.     cout << "請依次輸入學生的編號:" << endl;
  17.     for (char ch; cin >> ch, ch !='#';) {
  18.         q = new Note;
  19.         p->next = q;
  20.         q->ch = ch;
  21.         cout << q->ch << " ";
  22.         p = q;
  23.         length++;
  24.     }
  25.      p->next=first->next;
  26. }
  27. void searchNote(node first,int n) {
  28.   
  29.     cout << "出隊的順序依次是:" << endl;
  30.     while (true) {                   //死迴圈,為了找出所有標識結點
  31.         for (int i = 1; i <=n; i++) {
  32.                 
  33.                 first = first->next;
  34.                 if (first->ch == NULL){ //只要迴圈到ch為空的結點,i減1,並且繼續執行for迴圈
  35.                     i--;
  36.                     continue;
  37.                 }
  38.         }
  39.             flag++;    //只要結點的first->ch=NULL,則標識就增加1
  40.             cout << first->ch << " ";
  41.             if (flag == length) {  //已經找到了所有的標識結點,退出死迴圈
  42.                 break;
  43.             }
  44.             first->ch = NULL;//把標識結點的資料域置為空
  45.     }
  46.     cout << endl;
  47.     cout << "獲勝的同學是:" << endl;
  48.     cout << first->ch;    //列印出獲勝者
  49. }
  50. void deleteNote(node q) {
  51.     node p = q;
  52.     for (; p != q; p = p->next) {
  53.         node no = p;
  54.         delete no;
  55.     }
  56.     cout << "環已銷燬!!!" << endl;
  57. }
  58. int main() {
  59.     Note note;
  60.     initNote(&note);
  61.     createNote(&note);
  62.     cout << endl;
  63.     searchNote(&note,4);
  64.     cout << endl;
  65.     deleteNote(&note);
  66. }
執行結果:

形成環這裡不必多說,關鍵在於void searchNote(node first,int n),思路就是找到同學後,把該同學貼上標籤,然後繼續迴圈該環,當找到已經被貼上標籤的同學,就跳過該同學,當找到所有的同學後,那麼剩下的同學就是獲勝 者,當然別忘了,遊戲結束後,不能讓同學還是手拉手圍成一個環,那就是void deleteNote(node q)的功能啦,把該環"銷燬"了。上面的解題思路,我想很多朋友會想到,可不可以用陣列解決該問題,當然可以啦!關鍵是清晰的畫出程式流程圖解,程式寫起來會變的相對容易些。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29876893/viewspace-1851818/,如需轉載,請註明出處,否則將追究法律責任。

相關文章