数据结构---队列的基本操作
队列的表示和操作
只允许在一端插入数据,在另一端删除数据的特殊线性表,具有先进先出的特性(FIFO)
队尾插入---入队 队首删除---出队
队列的抽象数据类型定义
ATD Queue{
数据对象:D={ai属于ElemSet ,i=l,2,…, n ,n>=O}
数据关系:R={ <ai-1,ai> |ai-1,ai属于D , i=2, …, n}
约定其中a1端为队列头,an端为队列尾。
基本操作:
}ATD Queue
顺序队列
分配了一块连续的存储单元来存储队列中的元素,并附设了两个指针front和rear指示队头元素和队尾元素
其中,队头指针指向队头元素,队尾指针指向队尾元素的下一个位置(并不是指针类型,整型来记录数组的下标)
#define MAXSIZE 100//最大队列长度
typedef struct {
ElemType data[MAXSIZE];//初始化的动态分配存储空间
int front,rear;//头指针,尾指针
} SqQueue;
队空:Q.front= =Q.rear= = 0
入队:队不满,在队尾添加元素,队尾指针加一
出队:队非空,在队首删除元素,队首指针加一
队满:Q.rear==MAXSIZE 发生溢出
真溢出:front=0,Q.rear=MAXSIZE,再入队就真溢出
假溢出:front!=0,rear=MAXSIZE,实际还有空的位置,只不过队首指针后面无空间
解决方法:
1.将队中元素向队头方向移动(浪费时间)
2.循环队列
当Q.front==MAXSIZE-1,在添加元素front自动到0(实现方式:求余)
队首指针进1:Q.front = (Q.front + 1)% MAXSIZE;
队尾指针进1:Q.rear = (Q.rear + 1)% MAXSIZE;
队列长度:(Q.front + MAXSIZE - Q.rear) % MAXSIZE;
区别队满队空:
- 少用一个元素空间---即队列空间大小为m时,有m-1个元素就认为是队满。
队空: Q.front = Q.rear
队满: (Q rear+ 1)%MAXSIZE = Q.front
- 另设一个标志位以区别队列是 “空” 还是 “满"
队空:tag ==0 ,若因删除导致Q.front == Q.rear
队满:tag == 1,若因添加导致Q.front == Q.rear
- 设置一个变量,记录元素的个数
队空:Q.size == 0
队满:Q.size == MAXSIZE
循环队列的操作
#include<iostream>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef char QElemType;
typedef int status;
typedef struct
{
QElemType* base;
int front, rear;
}SqQueue;
//初始化队列
status InitQueue(SqQueue& Q)
{
Q.base = new QElemType[MAXSIZE];
if (!Q.base)
{
return OVERFLOW;
}
Q.front = Q.rear = 0;
return OK;
}
//销毁队列
status DestroyQueue(SqQueue& Q)
{
if (Q.front != Q.rear)
{
delete Q.base;
Q.base = NULL;
Q.front = Q.rear = 0;
return OK;
}
return ERROR;
}
//清空队列
status ClearQueue(SqQueue& Q)
{
if (Q.front != Q.rear)
{
Q.front = Q.rear = 0;
return OK;
}
return ERROR;
}
//判断队列是否为空
bool QueueEmpty(SqQueue Q)
{
if (Q.front == Q.rear)
return true;
else
return false;
}
//获取队列长度
int GetLengthQueue(SqQueue Q)
{
int Length;
Length = (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
return Length;
}
//获取队首元素
QElemType GetHeadQueue(SqQueue Q)
{
if (Q.front != Q.rear)
{
return *(Q.base + Q.front);
}
else
return NULL;
}
//入队
status EnQueue(SqQueue& Q, QElemType& e)
{
if ((Q.rear + 1) % MAXSIZE == Q.front)//判断是否队满
return ERROR;
e = Q.base[Q.front];//在队首入队
Q.front = (Q.front + 1) % MAXSIZE;//队首指针增1,避免假溢出所以求余
return OK;
}
//出队
status DeQueue(SqQueue& Q, QElemType& e)
{
if (Q.front == Q.rear)//判断是否队空
return ERROR;
e = Q.base[Q.front];
Q.front = (Q.front + 1) % MAXSIZE;
return OK;
}
int main()
{
SqQueue Q;
InitQueue(Q);
if (InitQueue(Q))
{
cout << "初始化成功!" << endl;
}
else
cout << "初始化失败!"<<endl;
char A,B;
for (int i = 0; i <= 5; i++)
{
cout << "请输入第" << i + 1 << "个数据:";
cin >> A;
EnQueue(Q, A);
}
cout << "第一个数据是:" << GetHeadQueue(Q);
cout << "队列长度为:" << GetLengthQueue(Q);
for (int j = 0; j <= 2; j++)
{
DeQueue(Q, B);
cout << "输出第" << j + 1 << "个数据:" << B << endl;
}
ClearQueue(Q);
if (QueueEmpty(Q))
{
cout << "队列为空!" << endl;
}
DestroyQueue(Q);
return 0;
}