目录
前言
这篇博客主要是介绍队列的顺序存储表示和实现。
1.队列的顺序存储方式的实现
我们使用一组地址连续的存储单元依次存放从对头和队尾的元素之外,还需要设置两个指针front和rear分别表示队列头元素和队列尾元素的位置。我们规定,初始化队列的时候front=rear= 0。每当插入新的队尾元素的时候,尾指针+1;删除对头元素之后,头指针+1.因此对于非空队列,头指针指向对头元素,尾指针指向尾不元素的下一个位置。
图1.头指针、尾指针和队列中数据元素之间的关系
1.定义
#define MAXQSIZE 100 // 最大队列长度
struct SeqListQueue{
int *base;
int front;
int rear;
};
2.初始化
初始化的时候头指针和尾指针均为0。
// 队列初始化
Status initQueue(SeqListQueue &seqQueue) {
seqQueue.base = new int[MAXQSIZE]; // 分配存储空间
if (!seqQueue.base) {
return 0;
}
seqQueue.front = seqQueue.rear = 0; // 初始时,队头和队尾指针都指向队列的头部
return 1;
}
3.销毁
销毁顺序队列的时候,我们删除动态分配的存储空间,然后置空指针。
// 销毁队列
void destroyQueue(SeqListQueue &seqQueue) {
if (seqQueue.base) {
delete[] seqQueue.base; // 释放存储空间
seqQueue.base = nullptr; // 将指针置空
}
}
4.清空队
队头和队尾指针重置为零即可。
void clearQueue(SeqListQueue &seqQueue) {
seqQueue.front = seqQueue.rear = 0; // 将队头和队尾指针重置为初始位置
}
5.队空判断
队首和队尾相同的时候,队列为空。
// 判断队列是否为空
bool isEmptyQueue(SeqListQueue seqQueue) {
return seqQueue.front == seqQueue.rear;
}
6.队长
这里使用尾指针减去头指针即为队列长度。
// 获取队列长度
int queueLength(SeqListQueue seqQueue) {
return seqQueue.rear - seqQueue.front;
}
7.清空
// 清空队列
void clearQueue(SeqListQueue &seqQueue) {
seqQueue.front = seqQueue.rear = 0; // 将 front 和 rear 指针重置为零
}
8.头元素
// 获取队列的队首元素
Status getSeqQueueHead(SeqListQueue seqQueue, int &head) {
if (seqQueue.front == seqQueue.rear) {
return 0; // 队列为空
}
head = seqQueue.base[seqQueue.front];
return 1;
}
9.入队
这里我做了一个动画来表示入队的过程:
// 入队
bool enQueue(SeqListQueue &seqQueue, int element) {
// 检查队列是否已满
if (seqQueue.rear == MAXQSIZE - 1) {
return false; // 队列已满
}
// 入队操作
seqQueue.base[++seqQueue.rear] = element;
return true;
}
10.出队
这里我做了一个动画展示出队的过程。
// 出队
bool deQueue(SeqListQueue &seqQueue, int &element) {
// 检查队列是否为空
if (seqQueue.front == seqQueue.rear) {
return false; // 队列为空,无法出队
}
// 出队操作
element = seqQueue.base[++seqQueue.front];
return true;
}
11.遍历顺序栈
// 遍历顺序栈
void traverseSeqQueue(SeqListQueue &queue) {
// 遍历队列中的元素
for (int i = queue.front + 1; i <= queue.rear; ++i) {
cout << queue.base[i] << " ";
}
cout << endl;
}
12.完整代码
#include <iostream>
using namespace std;
#include "linkQueue.hpp"
#include "sqQueue.hpp"
#define MAXQSIZE 100 // 最大队列长度
struct SeqListQueue{
int *base;
int front;
int rear;
};
// 队列初始化
Status initQueue(SeqListQueue &seqQueue) {
seqQueue.base = new int[MAXQSIZE]; // 分配存储空间
if (!seqQueue.base) {
return 0;
}
seqQueue.front = seqQueue.rear = 0; // 初始时,队头和队尾指针都指向队列的头部
return 1;
}
// 销毁
void destroyQueue(SeqListQueue &seqQueue) {
if (seqQueue.base) {
delete[] seqQueue.base; // 释放存储空间
seqQueue.base = nullptr; // 将指针置空
}
}
// 清空
void clearQueue(SeqListQueue &seqQueue) {
seqQueue.front = seqQueue.rear = 0; // 将队头和队尾指针重置为初始位置
}
// 判断队列是否为空
bool isEmptyQueue(SeqListQueue seqQueue) {
return seqQueue.front == seqQueue.rear; // 当队头和队尾指针相同时,队列为空
}
// 获取队列长度
int queueLength(SeqListQueue seqQueue) {
return seqQueue.rear - seqQueue.front;
}
// 获取队列的队首元素
Status getSeqQueueHead(SeqListQueue seqQueue, int &head) {
if (seqQueue.front == seqQueue.rear) {
return 0; // 队列为空
}
head = seqQueue.base[seqQueue.front];
return 1;
}
// 入队
bool enQueue(SeqListQueue &seqQueue, int element) {
// 检查队列是否已满
if (seqQueue.rear == MAXQSIZE - 1) {
return false; // 队列已满
}
// 入队操作
seqQueue.base[++seqQueue.rear] = element;
return true;
}
// 出队
bool deQueue(SeqListQueue &seqQueue, int &element) {
// 检查队列是否为空
if (seqQueue.front == seqQueue.rear) {
return false; // 队列为空,无法出队
}
// 出队操作
element = seqQueue.base[++seqQueue.front];
return true;
}
// 遍历顺序栈
void traverseSeqQueue(SeqListQueue &queue) {
// 遍历队列中的元素
for (int i = queue.front + 1; i <= queue.rear; ++i) {
cout << queue.base[i] << " ";
}
cout << endl;
}
int main() {
SeqListQueue seqQueue;
initQueue(seqQueue); // 初始化队列
// 测试入队
for (int i = 1; i <= 5; ++i) {
enQueue(seqQueue, i * 10);
}
// 输出队列元素
std::cout << "队列元素:";
traverseSeqQueue(seqQueue);
// 获取队首元素
int frontElement;
if (getSeqQueueHead(seqQueue, frontElement)) {
std::cout << "队首元素:" << frontElement << std::endl;
}
// 测试出队
int element;
for (int i = 0; i < 3; ++i) {
if (deQueue(seqQueue, element)) {
std::cout << "出队元素:" << element << std::endl;
}
}
// 输出队列元素
std::cout << "队列元素:";
traverseSeqQueue(seqQueue);
// 判断队列是否为空
if (isEmptyQueue(seqQueue)) {
std::cout << "队列为空" << std::endl;
} else {
std::cout << "队列不为空" << std::endl;
}
// 获取队列长度
std::cout << "队列长度为:" << queueLength(seqQueue) << std::endl;
// 清空队列
clearQueue(seqQueue);
// 判断队列是否为空
if (isEmptyQueue(seqQueue)) {
std::cout << "清空队列后,队列为空" << std::endl;
} else {
std::cout << "清空队列后,队列不为空" << std::endl;
}
// 销毁队列
destroyQueue(seqQueue);
return 0;
}