實驗三:數據結構之線性鏈表例程 實踐 循環單鏈表解決約瑟夫環問題

約瑟夫環(Josephus)由來:

約瑟夫環(Josephus)問題是由古羅馬的史學家約瑟夫(Josephus)提處的,他參加並記錄了公園66-70年猶太人反抗羅馬的起義。約瑟夫作爲一個將軍,設法守住了裘達伯特城達47天之久,在城市淪陷後,他和40名頑強的將士在附近的一個山洞避難。在那裏,這些叛亂者表決說“要投降毋寧死”。於是,決定了一個自殺方式。他們41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下一個重新報數,直到所有人都自殺身亡爲止。約瑟夫有預謀地將朋友和自己安排在第16個和第31個位置,逃過了這場死亡遊戲,並一起投降了羅馬。

約瑟夫問題具體描述是:N個人圍成一圈,從第一個開始報數,第M個將被殺掉,最後剩下一個。例如N=5,M=3,被殺掉的順序是:3,1,5,2,4。

實驗結果如圖:

約瑟夫問題:

實驗完整代碼如下:

  1 #include <stdio.h>
  2 #include <malloc.h>
  3 /*常量定義*/
  4 #define OK 0
  5 #define Err_Memory -1
  6 #define Err_InvalidParam -2
  7 typedef int Status;
  8 
  9 /*節點結構定義*/
 10 typedef int ElemType;
 11 typedef struct node{
 12     ElemType id;
 13     struct node *next;
 14 } *LinkList, ListNode;
 15 
 16 Status CreateList(LinkList Head, int n)
 17 {
 18     ListNode *p, *s;
 19     int i;
 20 
 21     if (!Head)
 22         return Err_InvalidParam;
 23 
 24     Head->next = Head;
 25     p = Head;
 26 
 27     for(i = 1; i<=n; i++){
 28         s = (ListNode *)malloc(sizeof(ListNode));
 29         s->id = i;
 30         s->next = p->next;
 31         p->next = s;
 32         p = p->next;
 33         printf("第%d個序號爲:%d\n", i, p->id);
 34     }
 35 
 36     return OK;
 37 }
 38 
 39 int Josephus(LinkList Head, int m)
 40 {
 41     int iCount = 1, iOrder = 0;
 42     ListNode *pcur, *pprev, *pdel;
 43 
 44     if (!Head)
 45         return Err_InvalidParam;
 46 
 47     pprev = Head;
 48     pcur = Head->next;
 49     while(pprev != pcur->next){
 50         if (pcur != Head && iCount == m){
 51             pdel = pcur;
 52             pprev->next = pcur->next;
 53             pcur = pcur->next;
 54             iOrder++;
 55             printf("第%d個出列序號爲:%d\n", iOrder, pdel->id);
 56             free(pdel);
 57             iCount = 1;
 58         } else {
 59             if (pcur != Head)
 60                 iCount ++;
 61             pprev = pcur;
 62             pcur = pcur->next;
 63         }
 64     }
 65 
 66     printf("第%d個出列序號爲:%d\n", ++iOrder, pcur->id);
 67     free(pcur);
 68     free(pprev);
 69 
 70     return OK;
 71 }
 72 
 73 void main()
 74 {
 75     int n, m;
 76     LinkList Joseph;
 77     printf("請輸入參與人數n:\n");
 78     scanf("%d", &n);
 79     printf("請輸入報數上限m:\n");
 80     scanf("%d", &m);
 81     Joseph = (ListNode *)malloc(sizeof(ListNode));
 82     if (CreateList(Joseph, n) != OK){
 83         printf("鏈表創建錯誤\n");
 84         return;
 85     }
 86     if(Joseph->next == Joseph){
 87         printf("參與人數輸入錯誤\n");
 88         return;
 89     }
 90     printf("\n");
 91     Josephus(Joseph, m);
 92 
 93 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章