目录

  • 队列的表示和操作
  • 队列的抽象数据类型定义
  • 顺序队列
  • 循环队列的操作

队列的表示和操作

只允许在一端插入数据,在另一端删除数据的特殊线性表,具有先进先出的特性(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;

数据结构与算法熊岳山第二版 队列的应用 数据结构队列基本操作_#define

队空: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;
}