PTA(栈和队列)1-7 另类循环队列

1-7 另类循环队列

分数 4

作者 DS课程组

单位 浙江大学

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

函数接口定义:

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

其中Queue结构定义如下:

1
2
3
4
5
6
7
8
9
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。

裁判测试程序样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#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;
}

/* 你的代码将被嵌在这里 */

输入样例:

1
2
3
4
5
6
7
8
9
10
11
12
4
Del
Add 5
Add 4
Add 3
Del
Del
Add 2
Add 1
Add 0
Add 10
End

输出样例:

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

  • 这题没有尾指针,但是可以根据头指针+队列中的个数计算出来
  • 此循环队列还是先进先出,还是要使Front指针是队头

答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bool AddQ( Queue Q, ElementType X ) {
// 观察CreateQueue发现此队列是带头结点的
if(Q->Count == Q->MaxSize) {
printf("Queue Full\n");
return false;
}
// 计算队尾位置
int rear = (Q->Front + Q->Count) % Q->MaxSize;
Q->Data[rear] = X;
Q->Count++;
return true;
}

ElementType DeleteQ( Queue Q ) {
if (Q->Count == 0) {
printf("Queue Empty\n");
return ERROR;
}
ElementType elem = Q->Data[Q->Front];
Q->Front = (Q->Front + 1) % Q->MaxSize;
Q->Count--;
return elem;
}