另类循环队列

    技术2022-07-11  97

    如果用一个循环数组表示队列,并且只设队列头指针Front,不设尾指针Rear,而是另设Count记录队列中元素个数。请编写算法实现队列的入队和出队操作。

    函数接口定义:

    bool AddQ( Queue Q, ElementType X ); ElementType DeleteQ( Queue Q );

    其中Queue结构定义如下:

    typedef int Position; typedef struct QNode *PtrToQNode; struct QNode { ElementType *Data; /* 存储元素的数组 */ Position Front; /* 队列的头指针 */ int Count; /* 队列中元素个数 */ int MaxSize; /* 队列最大容量 */ }; typedef PtrToQNode Queue;

    注意:如果队列已满,AddQ函数必须输出“Queue Full”并且返回false;如果队列是空的,则DeleteQ函数必须输出“Queue Empty”,并且返回ERROR。

    裁判测试程序样例:

    #include <stdio.h> #include <stdlib.h> #define ERROR -1 typedef int ElementType; typedef enum { addq, delq, end } Operation; typedef enum { false, true } bool; typedef int Position; typedef struct QNode *PtrToQNode; struct QNode { ElementType *Data; /* 存储元素的数组 */ Position Front; /* 队列的头、尾指针 */ int Count; /* 队列中元素个数 */ int MaxSize; /* 队列最大容量 */ }; typedef PtrToQNode Queue; Queue CreateQueue( int MaxSize ) { Queue Q = (Queue)malloc(sizeof(struct QNode)); Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType)); Q->Front = 0; Q->Count = 0; Q->MaxSize = MaxSize; return Q; } bool AddQ( Queue Q, ElementType X ); ElementType DeleteQ( Queue Q ); Operation GetOp(); /* 裁判实现,细节不表 */ int main() { ElementType X; Queue Q; int N, done = 0; scanf("%d", &N); Q = CreateQueue(N); while ( !done ) { switch( GetOp() ) { case addq: scanf("%d", &X); AddQ(Q, X); break; case delq: X = DeleteQ(Q); if ( X!=ERROR ) printf("%d is out\n", X); break; case end: while (Q->Count) printf("%d ", DeleteQ(Q)); done = 1; break; } } return 0; } /* 你的代码将被嵌在这里 */

    输入样例:

    4 Del Add 5 Add 4 Add 3 Del Del Add 2 Add 1 Add 0 Add 10 End

    输出样例:

    Queue Empty 5 is out 4 is out Queue Full 3 2 1 0

    下面用图来解释一下: 刚开始插入三个元素: 然后两次出队列: 再将2入队列,此时队列的最顶部已经被占完了,但我们看到还可以继续入队列,说明这是一个循环队列。队列的尾指针就是这道题的关键,此时Q.front=2,Q.count=2,尾指针此时应该为0,所以可以知道尾指针就是**(Q.front+Q.count)%Q.MaxSize** 然后除了尾指针就是头指针,因为是循环队列,所以头指针每次的变化应该是Q.front=(Q.front+1)%Q.MaxSize; 还有就是判断队列满和空的条件,因为Q.count是用来记录元素的,所以队列满和空通过Q.count就很容易判断,Q.count=0就是队空,Q.count=Q.MaxSize就是队满。还有就是记得出队列记得将Q.count-1,入队列记得+1. 代码实现:

    bool AddQ( Queue Q, ElementType X ) {//插入操作 改变队尾(Q->Front+Q->Count)%Q->MaxSize) if(Q->MaxSize==Q->Count ) { printf("Queue Full\n"); return false; } else { Q->Count ++; Q->Data [(Q->Front+Q->Count) %Q->MaxSize ]=X; return true; } } ElementType DeleteQ( Queue Q ) {//删除操作就是改变队首(Q->Front+1)%Q->MaxSize if(Q->Count ==0) { printf("Queue Empty\n"); return ERROR; } else { Q->Count-- ; Q->Front =(Q->Front +1)%Q->MaxSize ; return Q->Data [Q->Front ]; } }
    Processed: 0.017, SQL: 9