另类循环队列
如果用一个循环数组表示队列,并且只设队列头指针Front,不设尾指针Rear,而是另设Count记录队列中元素个数。请编写算法实现队列的入队和出队操作。
Code:
#include <bits/stdc++.h>
using namespace std;
const int M = 100;
int q[100], Front = 0, Count = 0;//front指向第一个元素
bool push(int x){
if(Count >= M) return false;
else {
q[(Front + (Count ++ ) )%M] = x;
return true;
}
}
int pop(){
if(Count <= 0) return INT32_MIN;
else {
return q[Front + ( -- Count)];
}
}
void show(){
cout << "当前队列内的元素为:";
for(int i = 0; i < Count; ++i)
cout << q[(Front + i)%M] << " ";
cout << endl;
}
int main(){
cout << "请选择操作: 1.入队, 2.出队, -1.退出" << endl;
int op, p;
cin >> op;
while(op != -1){
int x;
switch (op){
case 1:
cin >> x;
push(x);
show();
break;
case 2:
p = pop();
if(p == INT32_MIN) cout << "队列为空" << endl;
else cout << "出队的元素为:" << pop() << endl;
break;
default:
cout << "指令错误" << endl;
}
cout << "请选择操作: 1.入队, 2.出队, -1.退出" << endl;
cin >> op;
}
}
运行代码截图:
另:PTA原题
如果用一个循环数组表示队列,并且只设队列头指针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
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
Code:
bool AddQ( Queue Q, ElementType X ){
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 ){
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 ];
}
}
双端队列
双端队列(deque,即double-ended queue的缩写)是一种具有队列和栈性质的数据结构,即可以(也只能)在线性表的两端进行插入和删除。若以顺序存储方式实现双端队列,请编写例程实现下列操作:
Push(X,D):将元素X插入到双端队列D的头;
Pop(D):删除双端队列D的头元素,并返回;
Inject(X,D):将元素X插入到双端队列D的尾部;
Eject(D):删除双端队列D的尾部元素,并返回。
思路:
Push(X,D):将元素X插入到双端队列D的头;(front -- )
Pop(D):删除双端队列D的头元素,并返回;(front ++)
Inject(X,D):将元素X插入到双端队列D的尾部;(rear ++ )
Eject(D):删除双端队列D的尾部元素,并返回。(rear -- )
Code:
#include <bits/stdc++.h>
using namespace std;
class Deque{
private:
int front, rear, Count;
int *p;
public:
static int MAX_SIZE;
Deque();
~Deque(){ delete p;}
bool push(int x);
int pop();
bool inject(int x);
int eject();
bool is_full();
bool is_empty();
void show();
};
int Deque::MAX_SIZE = 100;
Deque::Deque() : front(0), rear(1), Count(0){
p = new int[Deque::MAX_SIZE];
}
bool Deque::push(int x){
if(is_full()) return false;
else {
p[front] = x;
front = (front-1+Deque::MAX_SIZE)%Deque::MAX_SIZE;
Count++;
}
}
int Deque::pop(){
if(is_empty()) return INT32_MIN;
else {
front = (front+1)%Deque::MAX_SIZE;
Count--;
return p[front];
}
}
bool Deque::inject(int x){
if(is_full()) return false;
else {
p[rear] = x;
rear = (rear+1)%Deque::MAX_SIZE;
Count++;
}
}
int Deque::eject(){
if(is_empty()) return INT32_MIN;
else {
rear = (rear-1+Deque::MAX_SIZE)%Deque::MAX_SIZE;
Count--;
return p[rear];
}
}
bool Deque::is_full(){
return Count == Deque::MAX_SIZE;
}
bool Deque::is_empty(){
return Count == 0;
}
void Deque::show(){
cout << "当前队列中的元素: ";
for(int i = 1; i <= Count; ++i)
cout << p[(front+i)%Deque::MAX_SIZE] << " ";
cout << endl;
}
int main(){
Deque dq;
int op;
do{
cout << "请输入操作:\n1.队头入队\t2.队头出队\t3.队尾入队\t4.队尾出队\t-1.结束\n";
cin >> op;
int x, tmp;
switch(op){
case 1:
cin >> x;
dq.push(x);
dq.show();
break;
case 2:
tmp = dq.pop();
if(tmp == INT32_MIN) cout << "队列为空\n";
else cout << "出队元素为" << tmp << endl;
break;
case 3:
cin >> x;
dq.inject(x);
dq.show();
break;
case 4:
tmp = dq.eject();
if(tmp == INT32_MIN) cout << "队列为空\n";
else cout << "出队元素为" << tmp << endl;
break;
default:
if(op != -1) cout << "指令错误\n";
}
}while(op != -1);
}
注意:双端队列仍然是循环队列,否则存在假溢出。
运行代码截图:
另:PTA原题
双端队列(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
。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
typedef int ElementType;
typedef enum { push, pop, inject, eject, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode {
ElementType *Data; /* 存储元素的数组 */
Position Front, Rear; /* 队列的头、尾指针 */
int MaxSize; /* 队列最大容量 */
};
typedef PtrToQNode Deque;
Deque CreateDeque( int MaxSize )
{ /* 注意:为区分空队列和满队列,需要多开辟一个空间 */
Deque D = (Deque)malloc(sizeof(struct QNode));
MaxSize++;
D->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
D->Front = D->Rear = 0;
D->MaxSize = MaxSize;
return D;
}
bool Push( ElementType X, Deque D );
ElementType Pop( Deque D );
bool Inject( ElementType X, Deque D );
ElementType Eject( Deque D );
Operation GetOp(); /* 裁判实现,细节不表 */
void PrintDeque( Deque D ); /* 裁判实现,细节不表 */
int main()
{
ElementType X;
Deque D;
int N, done = 0;
scanf("%d", &N);
D = CreateDeque(N);
while (!done) {
switch(GetOp()) {
case push:
scanf("%d", &X);
if (!Push(X, D)) printf("Deque is Full!\n");
break;
case pop:
X = Pop(D);
if ( X==ERROR ) printf("Deque is Empty!\n");
else printf("%d is out\n", X);
break;
case inject:
scanf("%d", &X);
if (!Inject(X, D)) printf("Deque is Full!\n");
break;
case eject:
X = Eject(D);
if ( X==ERROR ) printf("Deque is Empty!\n");
else printf("%d is out\n", X);
break;
case end:
PrintDeque(D);
done = 1;
break;
}
}
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
3
Pop
Inject 1
Pop
Eject
Push 2
Push 3
Eject
Inject 4
Inject 5
Inject 6
Push 7
Pop
End
输出样例:
Deque is Empty!
1 is out
Deque is Empty!
2 is out
Deque is Full!
Deque is Full!
3 is out
Inside Deque: 4 5
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
Code:
bool Push(ElementType X, Deque D){
if((D -> Rear + 1) % D -> MaxSize == D -> Front){//队满
return false;
}
D -> Front = (D->Front -1 + D -> MaxSize) % D -> MaxSize;//front --
D -> Data[D -> Front] = X;
return true;
}
// ElementType Pop( Deque D ){
// if(D -> Rear == D -> Front){//队空
// return ERROR;
// }
// D -> Front = (D -> Front + 1) % D -> MaxSize;//front ++
// return D->Data[D -> Front];
// }
ElementType Pop( Deque D ){
int temp;//!!!!!!!!!!!!!!临时变量,储存pop前的data。
if(D -> Rear == D -> Front){
return ERROR;
}
temp = D->Front;
D -> Front = (D -> Front + 1 ) % D -> MaxSize;
return D -> Data[temp];
}
bool Inject( ElementType X, Deque D ){
if((D -> Rear + 1) % D -> MaxSize == D -> Front){//队满
return false;
}
D -> Data[D -> Rear] = X;//注意:数组从0开始到Maxsize - 1,故插入尾部只需Data[D -> Rear] 不需要Data[D -> Rear + 1]
D -> Rear = (D -> Rear + 1) % D -> MaxSize;//rear ++
return true;
}
ElementType Eject( Deque D ){
if(D -> Rear == D -> Front){//队空
return ERROR;
}
D -> Rear = (D -> Rear - 1 + D -> MaxSize) % D -> MaxSize;rear --
return D -> Data[D -> Rear];
}