约瑟夫环问题
循环队列实现约瑟夫环
第三次数据结构实验:
约瑟夫环的实现:设有n个人围坐在圆桌周围,现从某个位置 i 上的人开始报数,数到 m 的人就站出来。下一个人,即原来的第m+1个位置上的人,又从1开始报数,再是数到m的人站出来。依次重复下去,直到全部的人都站出来,按出列的先后又可得到一个新的序列。由于该问题是由古罗马著名的史学家Josephus提出的问题演变而来,所以通常称为Josephus 问题。
例如:当n=8,m=4,i=1时,得到的新序列为:
4,8,5,2,1,3,7,6
编写程序选择循环队列作为存储结构模拟整个过程,并依次输出出列的各人的编号。
1 #include <iostream>
2 #include <malloc.h>
3 using namespace std;
4
5 #define TRUE 1
6 #define FALSE 0
7 #define OK 1
8 #define ERROR 0
9 #define OVERFLOW -2
10 #define INFEASIBLE -1
11
12 typedef int Status;
13 typedef int QElemType;
14 int MAXQSIZE;
15
16 typedef struct{
17 QElemType *base;
18 int front;
19 int rear;
20 }SqQueue;
21
22 Status InitQueue(SqQueue& Q)
23 {
24 Q.base = (QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
25 if(!Q.base)
26 exit(OVERFLOW);
27 Q.front = Q.rear = 0;
28
29 return OK;
30 }
31
32 Status EnQueue(SqQueue& Q,QElemType e)
33 {
34 if((Q.rear+1)%MAXQSIZE == Q.front)
35 return ERROR;
36 Q.base[Q.rear] = e;
37 Q.rear = (Q.rear+1)%MAXQSIZE;
38
39 return OK;
40 }
41
42 Status DeQueue(SqQueue& Q,QElemType& e)
43 {
44 if (Q.front == Q.rear)
45 return ERROR;
46 e = Q.base[Q.front];
47 Q.base[Q.front] = 0;
48 Q.front = (Q.front+1)%MAXQSIZE;
49
50 return OK;
51
52 }
53
54 Status Josephus(SqQueue& Q,int m)
55 {
56 cout<<"The Josephus Ring Count:"<<endl;
57 while(TRUE)
58 {
59 int i = 1;
60 int num = 0;
61 while (i++ != m)
62 {
63 DeQueue(Q,num);
64
65 EnQueue(Q,num);
66
67 }
68 DeQueue(Q,num);
69 cout<<num<<" ";
70 if (Q.front == Q.rear)
71 break;
72 }
73 cout<<endl;
74
75 return OK;
76
77 }
78
79 int main()
80 {
81 SqQueue que;
82 int m,n;
83 cout<<"Please input the n:";
84 cin>>n;
85 cout<<"Please input the m:";
86 cin>>m;
87 MAXQSIZE = ++n;
88 InitQueue(que);
89
90 for(int i =1;i<=n;i++)
91 {
92 EnQueue(que,i);
93 }
94
95 Josephus(que,m);
96
97 return 0;
98
99
100
101
102 }
2 #include <malloc.h>
3 using namespace std;
4
5 #define TRUE 1
6 #define FALSE 0
7 #define OK 1
8 #define ERROR 0
9 #define OVERFLOW -2
10 #define INFEASIBLE -1
11
12 typedef int Status;
13 typedef int QElemType;
14 int MAXQSIZE;
15
16 typedef struct{
17 QElemType *base;
18 int front;
19 int rear;
20 }SqQueue;
21
22 Status InitQueue(SqQueue& Q)
23 {
24 Q.base = (QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
25 if(!Q.base)
26 exit(OVERFLOW);
27 Q.front = Q.rear = 0;
28
29 return OK;
30 }
31
32 Status EnQueue(SqQueue& Q,QElemType e)
33 {
34 if((Q.rear+1)%MAXQSIZE == Q.front)
35 return ERROR;
36 Q.base[Q.rear] = e;
37 Q.rear = (Q.rear+1)%MAXQSIZE;
38
39 return OK;
40 }
41
42 Status DeQueue(SqQueue& Q,QElemType& e)
43 {
44 if (Q.front == Q.rear)
45 return ERROR;
46 e = Q.base[Q.front];
47 Q.base[Q.front] = 0;
48 Q.front = (Q.front+1)%MAXQSIZE;
49
50 return OK;
51
52 }
53
54 Status Josephus(SqQueue& Q,int m)
55 {
56 cout<<"The Josephus Ring Count:"<<endl;
57 while(TRUE)
58 {
59 int i = 1;
60 int num = 0;
61 while (i++ != m)
62 {
63 DeQueue(Q,num);
64
65 EnQueue(Q,num);
66
67 }
68 DeQueue(Q,num);
69 cout<<num<<" ";
70 if (Q.front == Q.rear)
71 break;
72 }
73 cout<<endl;
74
75 return OK;
76
77 }
78
79 int main()
80 {
81 SqQueue que;
82 int m,n;
83 cout<<"Please input the n:";
84 cin>>n;
85 cout<<"Please input the m:";
86 cin>>m;
87 MAXQSIZE = ++n;
88 InitQueue(que);
89
90 for(int i =1;i<=n;i++)
91 {
92 EnQueue(que,i);
93 }
94
95 Josephus(que,m);
96
97 return 0;
98
99
100
101
102 }
应该说还算简单,只是测试下循环队列的使用而已..。估计其它方法更简单些..。
那个判断结束标志浪费了我很长时间:
if (Q.front == Q.rear)
break;
正常情况下循环队列满的条件应该是:
if (Q.front == (Q.rear+1)%MAXQSIZE)
break;
问题是这个不正常,呵呵,它不是判断队满,而是判断结束而已..。
一直删除操作,怎么会满嘛,结束时应该是所有元素都0了..。
------By 0x0o
Time: 08.10.25 23:55