一道模拟题:改进的Joseph环

题目:改进的Joseph环。一圈人报数,报数上限依次为3,7,11,19,循环进行,直到所有人出列完毕。

思路:双向循环链表模拟。

代码:

 1 #include <cstdio>
 2 #include <cstdlib>
 3 
 4 #define N 20
 5 
 6 typedef struct node
 7 {
 8     int id;
 9     struct node *next;
10     struct node *pre;
11 }Node, *pNode;
12 
13 //双向循环链表的构建
14 pNode RingConstruct (int n)
15 {
16     int i;
17     pNode head, p, q;
18     head = (pNode)malloc(sizeof(Node));
19     head->id = 1;
20     p = head;
21     for (i = 2; i <= n; i++)
22     {
23         q = (pNode)malloc(sizeof(Node));
24         q->id = i;
25         p->next = q;
26         q->pre = p;
27         p = q;
28     }
29     p->next = head;
30     head->pre = p;
31     return head;
32 }
33 
34 //传入报数的次数序号,返回此次报数的上限值
35 int boundMachine (int order)
36 {
37     int boundList[4] = {3, 7, 11, 19};
38     return boundList[(order - 1)%4];
39 }
40 
41 //first为每次报数的第一人,bound为此次报数的上限,返回此次报数的应出列者
42 pNode count (pNode first, int bound)
43 {
44     while (--bound)
45     {
46         first = first->next;
47     }
48     return first;
49 }
50 
51 //将currentNode从环中删除,并返回被删除节点的下一节点
52 pNode removeNode (pNode currentNode)
53 {
54     pNode first = currentNode->next;
55     if (first != currentNode)
56     {
57         currentNode->pre->next = first;
58         first->pre = currentNode->pre;
59     }
60     printf("%d ", currentNode->id);
61     free(currentNode);
62     return first;
63 }
64 
65 int main (int argc, char *argv)
66 {
67     pNode first, toRemove;
68     int i;
69     first = RingConstruct(N);
70     for (i = 1; i <= N; i++)
71     {
72         toRemove = count(first, boundMachine(i));
73         first = removeNode(toRemove);
74     }
75     return 0;
76 }

当N为20时,出列顺序是:

posted @ 2016-11-24 20:09  jiu~  阅读(599)  评论(0编辑  收藏  举报