循环队列

    循环队列结构如下:

#define QUEUE_MAXSIZE 100
#define ERROR           0
#define OK              1
#define OVERFLOW       -1

typedef int Status;
typedef int QElemType;
typedef struct
{
    QElemType *data;
    int front;
    int rear;
}SqQueue;

    下面是具体实现:

//初始化时,队头队尾皆为空
//当加入元素后,front指向队头的位置
//rear指向队尾的下一个元素位置 
void InitQueue(SqQueue *Q)
{
    assert(Q);

    Q->data = (QElemType *)malloc(sizeof(QElemType)*QUEUE_MAXSIZE);
    if (!Q->data)
        exit(OVERFLOW);

    Q->front = Q->rear = 0;
}

void DestroyQueue(SqQueue *Q)
{
    assert(Q);

    free(Q->data);
    Q->data=NULL;
    Q->front = Q->rear = 0;
}

void ClearQueue(SqQueue *Q)
{
    assert(Q);

    Q->front = Q->rear = 0;
}

Status QueueEmpty(SqQueue *Q)
{
    assert(Q);

    return Q->front == Q->rear;
}

int QueueLength(SqQueue *Q)
{
    assert(Q);

    return (QUEUE_MAXSIZE + Q->rear - Q->front) % QUEUE_MAXSIZE;
}

Status EnQueue(SqQueue *Q, QElemType e)
{
    assert(Q);
//为了区分循环队列空和满的区别,要求队列满的状态有
//QUEUE_MAXSIZE-1个元素,而不是QUEUE_MAXSIZE个元素 
//当然,也可以最队列结构里设置一个标志,来区分满和空
    if ((Q->rear + 1) % QUEUE_MAXSIZE == Q->front)
        return ERROR;

    Q->data[Q->rear] = e;
    Q->rear = (Q->rear + 1) % QUEUE_MAXSIZE;

    return OK;
}

Status DeQueue(SqQueue *Q, QElemType *e)
{
    assert(Q);

    if (Q->rear == Q->front)
        return ERROR;

    if (e)
        *e = Q->data[Q->front];
    Q->front = (Q->front + 1) % QUEUE_MAXSIZE;

    return OK;
}

Status GetHead(SqQueue *Q,QElemType *e)
{
    assert(Q&&e);
    
    if(QueueEmpty(Q))
        return ERROR;
    
    *e=Q->data[Q->front];
    return OK;
}

void QueueTraverse(SqQueue *Q, void(*visit)(QElemType *))
{
assert(Q&&visit);
int tmp = Q->front; while (tmp != Q->rear) { visit(Q->data + tmp); tmp = (tmp + 1) % QUEUE_MAXSIZE; } }

    下面是测试程序:


  #include<stdio.h>
  #include<stdlib.h>
  #include<assert.h>

int main()
{
    SqQueue Q;
    int n = 90;

    InitQueue(&Q);

    while (n--)
        EnQueue(&Q, n);

    while (!QueueEmpty(&Q))
    {
        DeQueue(&Q, &n);
        printf("%d ", n);
    }

    system("pause");
    return 0;
}

    运行结果:

循环队列