实验三:数据结构之线性链表例程 实践 循环单链表解决约瑟夫环问题

约瑟夫环(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 }

 

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