双端队列的基本操作实现
双端队列
双端队列(deque,即double-ended queue的缩写)是一种具有队列和栈性质的数据结构,即可以(也只能)在线性表的两端进行插入和删除。若以顺序存储方式实现双端队列,请编写例程实现下列操作:
Push(D,e):将元素 e 插入到双端队列 D 的头;
Pop(D,e):删除双端队列 D 的头元素,并用 e 返回;
Inject(D,e):将元素 e 插入到双端队列 D 的尾部;
Eject(D,e):删除双端队列 D 的尾部元素,并用 e 返回。
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
typedef int ElemType;
typedef enum { push, pop, inject, eject, End } Operation;
typedef struct QNode
{
ElemType *Data; /* 存储元素的数组 */
int Front, Rear; /* 队列的头、尾指针 */
int MaxSize; /* 队列最大容量 */
}Deque;
bool CreateDeque(Deque &D, int MaxSize );
bool Push( Deque &D,ElemType e );
bool Pop( Deque &D,ElemType &e );
bool Inject( Deque &D,ElemType e );
bool Eject( Deque &D,ElemType &e );
Operation GetOp();
void PrintDeque( Deque D );
/*Push(D,e):将元素e插入到双端队列D的头;
Pop(D,e):删除双端队列D的头元素,并用e返回;
Inject(D,e):将元素e插入到双端队列D的尾部;
Eject(D,e):删除双端队列D的尾部元素,并用e返回。
注意:Push和Inject应该在正常执行完操作后返回true,或者在出现非正常情况时返回false。当Front和Rear相等时队列为空,Pop和Eject必须返回false,正常情况返回true。 */
bool Push( Deque &D,ElemType e )
{
/*************begin********************/
/* 请在这里完成代码 */
if ((D.Rear + 1) % D.MaxSize == D.Front) return false; // 队列满
D.Front = (D.Front - 1 + D.MaxSize) % D.MaxSize; // 环形队列,防止负数
D.Data[D.Front] = e;
return true;
/*************end********************/
}
bool Pop( Deque &D,ElemType &e )
{
/*************begin********************/
/* 请在这里完成代码 */
if (D.Front == D.Rear) return false; // 队列空
e = D.Data[D.Front];
D.Front = (D.Front + 1) % D.MaxSize;
return true;
/*************end********************/
}
bool Inject( Deque &D,ElemType e )
{
/*************begin********************/
/* 请在这里完成代码 */
if ((D.Rear + 1) % D.MaxSize == D.Front) return false; // 队列满
D.Data[D.Rear] = e;
D.Rear = (D.Rear + 1) % D.MaxSize;
return true;
/*************end********************/
}
bool Eject( Deque &D,ElemType &e )
{
/*************begin********************/
/* 请在这里完成代码 */
if (D.Front == D.Rear) return false; // 队列空
D.Rear = (D.Rear - 1 + D.MaxSize) % D.MaxSize; // 环形队列,防止负数
e = D.Data[D.Rear];
return true;
/*************end********************/
}
链队列的基本操作实现
#include<iostream>
#include <cstring>
using namespace std;
typedef int ElemType;
typedef int Status;
typedef enum { addq, delq, End } Operation;
typedef struct QNode
{
ElemType data;
struct QNode *next;
} QNode, *QueuePtr;
typedef struct
{
QueuePtr Front;
QueuePtr Rear;
} LinkQueue;
bool InitQueue(LinkQueue &Q); //带头结点单链表的初始化,返回true
bool EnQueue(LinkQueue &Q, ElemType e) ;
bool DeQueue(LinkQueue &Q, ElemType &e) ;
Operation GetOp(); //读取操作指令
//带头结点单链表的初始化,返回true
bool InitQueue(LinkQueue &Q)
{
/*************begin********************/
/* 请在这里完成代码 */
Q.Front = Q.Rear = (QueuePtr)malloc(sizeof(QNode)); // 创建头结点
if (!Q.Front) return false; // 内存分配失败
Q.Front->next = NULL; // 初始化为空队列
return true;
/*************end********************/
}
//实现入队操作,如果申请空间失败,返回false;否则返回true。
bool EnQueue(LinkQueue &Q, ElemType e)
{
/*************begin********************/
/* 请在这里完成代码 */
QueuePtr newNode = (QueuePtr)malloc(sizeof(QNode)); // 创建新结点
if (!newNode) return false; // 内存分配失败
newNode->data = e; // 赋值
newNode->next = NULL; // 新结点的next指针为NULL
Q.Rear->next = newNode; // 将新结点插入到队列尾部
Q.Rear = newNode; // 移动尾指针
return true;
/*************end********************/
}
//实现出队操作,如果队列是空的,则DeQueue函数必须输出“Queue Empty”,并且返回false,否则将队首的值赋给e,并返回true。
bool DeQueue(LinkQueue &Q, ElemType &e)
{
/*************begin********************/
/* 请在这里完成代码 */
if (Q.Front == Q.Rear) { // 队列为空
cout << "Queue Empty" << endl;
return false;
}
QueuePtr p = Q.Front->next; // 指向首元结点
e = p->data; // 获取首元结点的值
Q.Front->next = p->next; // 移除首元结点
if (Q.Rear == p) Q.Rear = Q.Front; // 如果队列只有一个结点,则出队后队列为空,尾指针指向头结点
free(p); // 释放内存
return true;
/*************end********************/
}
循环队列的基本操作实现
#include <iostream>
#include <cstring>
using namespace std;
typedef int ElemType;
typedef enum { addq, delq, End } Operation;
typedef struct QNode
{
ElemType *Data; /* 存储元素的数组 */
int Front; /* 队列的头 */
int Rear; /* 队列的尾 */
int MaxSize; /* 队列最大容量 */
} Queue;
bool CreateQueue( Queue &Q,int MaxSize );
bool AddQ( Queue &Q, ElemType X );
bool DeleteQ( Queue &Q,ElemType &X);
Operation GetOp(); //读取操作指令
/* 注意:为区分空队列和满队列,需要多开辟一个空间 */
//创建初始队列
bool CreateQueue( Queue &Q,int MaxSize )
{
/*************begin********************/
/* 请在这里完成代码 */
Q.Data = new ElemType[MaxSize + 1]; // 分配空间,多一个用于区分满和空
if (!Q.Data) return false; // 内存分配失败
Q.MaxSize = MaxSize;
Q.Front = Q.Rear = 0; // 初始化队列为空
return true;
/*************end********************/
}
//实现入队操作,如果队列已满,AddQ函数必须输出“Queue Full”并且返回false;否则返回true
bool AddQ( Queue &Q, ElemType X )
{
/*************begin********************/
/* 请在这里完成代码 */
if ((Q.Rear + 1) % (Q.MaxSize + 1) == Q.Front) { // 队列已满
cout << "Queue Full" << endl;
return false;
}
Q.Data[Q.Rear] = X; // 将元素X添加到队列尾部
Q.Rear = (Q.Rear + 1) % (Q.MaxSize + 1); // 移动尾指针
return true;
/*************end********************/
}
//实现出队操作,如果队列是空的,则DeleteQ函数必须输出“Queue Empty”,并且返回false,否则将队首的值赋给X,并返回true。
bool DeleteQ( Queue &Q,ElemType &X){
/*************begin********************/
/* 请在这里完成代码 */
if (Q.Front == Q.Rear) { // 队列为空
cout << "Queue Empty" << endl;
return false;
}
X = Q.Data[Q.Front]; // 获取队首元素
Q.Front = (Q.Front + 1) % (Q.MaxSize + 1); // 移动头指针
return true;
/*************end********************/
}