用C链表实现约瑟夫环问题

问题:设有n个人围成一个圆圈,现从第s个人开始报数,数到第m的人出列,然后从出列的下一个人重新开始报数,数到第m的人再次出列,如此反复,直到所有的人全部出列为止。对于任意给定的n、s、m,求按出列次序得到的n个人员的序列。

例:

图片就是问题简单示例,里面是每次要循环的数据,后面的S是出列的人

思路:

  1. 先创建一个链表,链表的长度就是n
  2. 从第s个节点开始循环
  3. 判断是否是第m个数
  4. 如果是第m个数,就输出并删除当前节点
  5. 循环到最后一个节点,再从第一个节点接着循环

主要代码:

 1 void yuesefu (LinkList * head, int n, int s, int m)
 2 {
 3     LinkList * p, * r, * q;
 4     int i = 1, j = n, k, l;
 5     p = GetData_LinkList(head, s);    //从第S位开始
 6     
 7     //判断是否循环完成
 8     while (j > 0) {
 9         //判断是否为第m个数
10         if (i == m) {
11             i = 0;
12             //输出这轮出局的人
13             printf("%d\n", p->data);
14             //存储当前节点的值
15             k = p->data;
16             
17             //删除当前节点
18             q = head->next;
19             l=1;
20             while (q != NULL) {
21                 //判断当前节点得值是否等于要删除的值
22                 if (q->data == k) {
23                     //删除节点
24                     DeleteNode_LinkList(head, l);
25                     break;
26                 }
27                 l++;
28                 q = q->next;
29             }
30             //从下一个节点开始循环
31             p = GetData_LinkList(head, l);
32             j--;
33         }else {
34             p = p->next;
35         }
36         //如果超出链表长度,再从第一个节点开始循环
37         if (p == NULL)
38             p = head->next;
39 
40         i++;
41     }
42     
43 }

 

整体代码:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 typedef int elemtype;
  5 
  6 typedef struct node
  7 {
  8     elemtype data;
  9     struct node * next;
 10 }LinkList;
 11 
 12 //创建链表
 13 LinkList * Create_LinkListF(int n)
 14 {
 15     int i;
 16     LinkList * head, * p;
 17     head = (LinkList *) malloc (sizeof(LinkList));
 18 
 19     if (head == NULL)
 20         return head;
 21 
 22     head->next = NULL;
 23 
 24     for (i=1; i<=n; i++) {
 25         p = (LinkList *) malloc (sizeof(LinkList));
 26 
 27         if (p == NULL)
 28             return head;
 29         
 30         p->data = i;
 31         p->next = head->next;
 32         head->next = p;
 33     }
 34 
 35     return head;
 36 }
 37 
 38 //按序号查找
 39 LinkList * GetData_LinkList (LinkList * head, int i)
 40 {
 41     LinkList * p;
 42     int j = 0;
 43     
 44     if (i <= 0)
 45         return NULL;
 46 
 47     p = head;
 48 
 49     while (p->next != NULL && j<i) {
 50         p = p->next;
 51         j++;
 52     }
 53 
 54     if (i == j)
 55         return p;
 56     else
 57         return NULL;
 58 }
 59 
 60 //删除节点
 61 int DeleteNode_LinkList (LinkList * head, int i)
 62 {
 63     LinkList * p, * r;
 64 
 65     if (i <= 0)
 66         p = NULL;
 67     else
 68         if (i == 1)
 69             p = head;
 70         else
 71             p = GetData_LinkList(head, i-1);
 72 
 73     if (p == NULL) {
 74         return 0;
 75     }else {
 76         r = p->next;
 77         if (r == NULL)
 78             return 0;
 79 
 80         p->next = r->next;
 81         free(r);
 82         return 1;
 83     }
 84     
 85 }
 86 
 87 void yuesefu (LinkList * head, int n, int s, int m)
 88 {
 89     LinkList * p, * r, * q;
 90     int i = 1, j = n, k, l;
 91     p = GetData_LinkList(head, s);    //从第S位开始
 92     
 93     //判断是否循环完成
 94     while (j > 0) {
 95         //判断是否为第m个数
 96         if (i == m) {
 97             i = 0;
 98             //输出这轮出局的人
 99             printf("%d\n", p->data);
100             //存储当前节点的值
101             k = p->data;
102             
103             //删除当前节点
104             q = head->next;
105             l=1;
106             while (q != NULL) {
107                 //判断当前节点得值是否等于要删除的值
108                 if (q->data == k) {
109                     //删除节点
110                     DeleteNode_LinkList(head, l);
111                     break;
112                 }
113                 l++;
114                 q = q->next;
115             }
116             //从下一个节点开始循环
117             p = GetData_LinkList(head, l);
118             j--;
119         }else {
120             p = p->next;
121         }
122         //如果超出链表长度,再从第一个节点开始循环
123         if (p == NULL)
124             p = head->next;
125 
126         i++;
127     }
128     
129 }
130 
131 int main (void)
132 {
133     int n, s, m;
134     LinkList * head;
135 
136     printf("n=");
137     scanf("%d", &n);
138 
139     printf("s=");
140     scanf("%d", &s);
141 
142     printf("m=");
143     scanf("%d", &m);
144 
145     head = Create_LinkListF(n);
146     yuesefu(head, n, s, m);
147 }

 

posted @ 2019-03-14 20:22  Hclle  阅读(507)  评论(0)    收藏  举报