约瑟夫环问题

循环队列实现约瑟夫环

第三次数据结构实验:

 

约瑟夫环的实现:设有n个人围坐在圆桌周围,现从某个位置 i 上的人开始报数,数到 m 的人就站出来。下一个人,即原来的第m+1个位置上的人,又从1开始报数,再是数到m的人站出来。依次重复下去,直到全部的人都站出来,按出列的先后又可得到一个新的序列。由于该问题是由古罗马著名的史学家Josephus提出的问题演变而来,所以通常称为Josephus 问题。    

    例如:当n=8,m=4,i=1时,得到的新序列为:

                48521376  

编写程序选择循环队列作为存储结构模拟整个过程,并依次输出出列的各人的编号。

 

 

 

  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 }

 

 

 

 

应该说还算简单,只是测试下循环队列的使用而已..。估计其它方法更简单些..。

那个判断结束标志浪费了我很长时间:

    if (Q.front == Q.rear)

           break;

正常情况下循环队列满的条件应该是:

       if (Q.front == (Q.rear+1)%MAXQSIZE)

           break;

问题是这个不正常,呵呵,它不是判断队满,而是判断结束而已..。

一直删除操作,怎么会满嘛,结束时应该是所有元素都0了..。

 

                           ------By 0x0o

                        Time:   08.10.25   23:55

posted @ 2008-10-26 00:00  端木  阅读(1017)  评论(2编辑  收藏  举报