双端队列(deque,即double-ended queue的缩写)是一种具有队列和栈性质的数据结构,即可以(也只能)在线性表的两端进行插入和删除。若以顺序存储方式实现双端队列,请编写例程实现下列操作:
Push(X,D)
:将元素X
插入到双端队列D
的头;Pop(D)
:删除双端队列D
的头元素,并返回;Inject(X,D)
:将元素X
插入到双端队列D
的尾部;Eject(D)
:删除双端队列D
的尾部元素,并返回。
函数接口定义:
bool Push( ElementType X, Deque D );
ElementType Pop( Deque D );
bool Inject( ElementType X, Deque D );
ElementType Eject( Deque D );
其中Deque
结构定义如下:
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode {
ElementType *Data; /* 存储元素的数组 */
Position Front, Rear; /* 队列的头、尾指针 */
int MaxSize; /* 队列最大容量 */
};
typedef PtrToQNode Deque;
注意:Push
和Inject
应该在正常执行完操作后返回true,或者在出现非正常情况时返回false。当Front
和Rear
相等时队列为空,Pop
和Eject
必须返回由裁判程序定义的ERROR
。
思路:
注意一点:Rear指向队列中有元素的后一个位置。如图:
所以,前插就是先移动再插入,后插就是先插入再移动,删除同理。
代码:
bool Push(ElementType X, Deque D) {
int l = D->Front;
int r = D->Rear;
int m = D->MaxSize;
if ((r + 1) % m== l)return false;
D->Front = (l + m - 1) % m;
D->Data[D->Front] = X;
return true;
}
ElementType Pop(Deque D) {
int l = D->Front;
int r = D->Rear;
int m = D->MaxSize;
if (l == r)return ERROR;
D->Front = (l + 1) % m;
ElementType x = D->Data[l];
return x;
}
bool Inject(ElementType X, Deque D) {
int l = D->Front;
int r = D->Rear;
int m = D->MaxSize;
if ((r + 1) % m == l)return false;
D->Data[r] = X;
D->Rear = (r + 1) % m;
return true;
}
ElementType Eject(Deque D) {
int l = D->Front;
int r = D->Rear;
int m = D->MaxSize;
if (l == r)return ERROR;
D->Rear = (r + m - 1) % m;
ElementType x = D->Data[D->Rear];
return x;
}