队列基础及其约瑟夫问题应用

队列是一种特殊的线性表,是运算受到限制的一种线性表,只允许在表的一端进行插入,而在另一端进行删除元素的线性表。队尾(rear)是允许插入的一端。队头(front)是允许删除的一端。空队列是不含元素的空表。根据这样的操作。队列特点是先进先出~

基础操作代码示例:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 5
#define TRUE 1
#define OK 1
#define FALSE 0
#define OVERFLOW 0
typedef int Status;
typedef int QElemType;
using namespace std;

typedef struct{
    QElemType *base;
    int front;
    int rear;
}SqQueue;

Status InitQueue(SqQueue *Q)
{//构建一个队列
    Q->base =(QElemType*)malloc(MAX*sizeof(QElemType));
    if(!Q->base)
        exit(OVERFLOW);
    Q->front=Q->rear=0;
    return OK;
}
Status  DestroyQueue(SqQueue *Q)
{
    if(Q->base)
        free(Q->base);
    Q->base=NULL;
    Q->front=Q->rear=0;
    return OK;
}
Status ClearQueue(SqQueue *Q)
{
    Q->front=Q->rear=0;
    return OK;
}
Status QueueEmpty(SqQueue Q)
{
    if(Q.front==Q.rear)
        return TRUE;
    else
        return FALSE;
}
int QueueLenth(SqQueue Q)
{
    return (Q.rear- Q.front+MAX)%MAX;
}
Status GetHead(SqQueue Q,QElemType *e)
{//取头顶元素
    if(Q.front==Q.rear)
        return FALSE;
    *e=Q.base[Q.front];
    return OK;
}
Status EnQueue(SqQueue *Q,QElemType e)
{//插入元素
    if((Q->rear+1)%MAX==Q->front)//满员
    {
        cout<<"队满"<<endl;
        return FALSE;
    }
    Q->base[Q->rear]=e;
    Q->rear = (Q->rear+1)%MAX;
    return OK;
}
Status DeQueue(SqQueue *Q,QElemType *e)
{//抛出元素
    if(Q->front==Q->rear)
        return FALSE;
    *e = Q->base[Q->front];
    Q->front = (Q->front+1)%MAX;
    return OK;
}
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3,1。
分析:
(1)由于对于每个人只有死和活两种状态,因此可以用布朗型数组标记每个人的状态,可用true表示死,false表示活。
(2)开始时每个人都是活的,所以数组初值全部赋为false。
(3)模拟杀人过程,直到所有人都被杀死为止。
注:循环入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列是"空"还是"满"。可以通过取模来判断:
完整代码:
#include <iostream>
using namespace std;

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;
typedef struct
{
    ElemType *base;
    int front;
    int rear;
    int MAXSIZE;
}SqQueue;
 
Status InitQueue(SqQueue& Q,int n)
{
    Q.base = new ElemType[100];
    if(!Q.base)
    {
        cout << "创建队列失败!";
        return ERROR;
    }
    Q.front=Q.rear=0;
    Q.MAXSIZE = n+1;//MAXSIZE是总人数+1,是为了留出一个空位置来放置rear
    return OK;
}
 
void QueueTraverse(SqQueue Q)
{
    int i;
    i=Q.front;
    while(i!=Q.rear)
    {
        cout<<Q.base[i]<<"  ";
        i=(i+1)%Q.MAXSIZE;
    }
    cout<<endl;
}
 
 
Status EnQueue(SqQueue& Q,ElemType e)
{
    if((Q.rear+1)%Q.MAXSIZE==Q.front)
    {
        cout << "队列已满!";
        return ERROR;
    }
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear+1)%Q.MAXSIZE;
    return OK;
}
 
Status DeQueue(SqQueue& Q,ElemType& e)
{
    if(Q.front==Q.rear)
    {
        cout << "队列为空!";
        return ERROR;
    }
    e = Q.base[Q.front];
    Q.base[Q.front] = 0;//0代表此位置没人: 
    Q.front = (Q.front+1)%(Q.MAXSIZE-1);//因为此时的MAXSIZE比总的人数大1,前面rear+1了;
    return OK;
}
int main()
{
    int n,m,i=1;
    SqQueue Q;
    ElemType e;
    cout << "请输入n个人(n<=100):";
    cin >> n;
    if(n>100 || n<1)
    {
        cout << "输入人数错误!";
        return 0;
    }
    InitQueue(Q,n);
    while(i<=n)//入队操作
    {
        EnQueue(Q,i);
        i++;
    }
    cout << "\n此时的序列顺序为:";
    QueueTraverse(Q);
    cout << "\n请输入第m个人出队(1<=m<=n):";
    cin >> m;
    if(m>n || m<1)
    {
        cout << "m输入错误!";
        return 0;
    }
    cout << endl;
    int Count = n;//用来记录剩下的人数
    while(Count != 1)
    {
        i = 1;//i用来控制是第几个人报数
        while(i != m)//当i的值不等于m的值时
        {
            Q.front = (Q.front+1)%(Q.MAXSIZE-1);//因为此时的MAXSIZE比总的人数大1,所以需要减去1,前面rear+1了;
            if(Q.base[Q.front] != 0)//当此时不为0的话,i++用来控制第几个人,0代表此位置没人: 
            {
                i++;
            }
        }
        DeQueue(Q,e);
        while(Q.base[Q.front] == 0)//当此时为0的时候,循环找到下一个不为0的位置
        {
            Q.front = (Q.front+1)%(Q.MAXSIZE-1);
        }
        cout << "序号:" << e << "出局!\n";
        Count--;
    }
    DeQueue(Q,e);
    cout << "最后一个是:" << e << endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/huiyuanai/p/9907547.html