目录
前言
1.队列的顺序存储方式的实现
1.定义
2.队列初始化
3.销毁
4.队列是否为空
5.队列长度
6.清空队列
7.队列头元素
8.入队
9.出队
10.完整代码
2.队列的链式存储方式的实现
1.定义
2.队列初始化
3.销毁
4.队列是否为空
5.队列长度
6.清空队列
7.队列头元素
8.入队
9.出队
10.完整代码
前言
队列也是一中受限的线性表,只能在表的一段进行插入操作,在表的另外一段进行删除操作
。和线性表一样,仍然是一对一的关系。存储结构也有两种方式:顺序队列和链队列。运算规则为先进先出。基本操作位入队或者出队,建空队列,判断队列为空或者队列已满等操作。
队列在现实中也有着很多的应用场景,例如离散事件的模拟、操作系统中的作业调度等。
队列仅在表尾进行插入操作,在表头进行删除操作。它是一种先进先出的线性表。
在队首删除元素成为出队,在队尾插入元素成为入队。
1.队列的顺序存储方式的实现
1.定义
#define MAXQSIZE 100 // 最大队列长度struct SeqListQueue{int *base;int front;int rear;
};
2.队列初始化
// 队列初始化
void initQueue(SeqListQueue &seqQueue){seqQueue.base = (int *)malloc(sizeof(int) * MAXQSIZE); // 为队列的数组成员分配内存空间if (!seqQueue.base) {std::cerr << "内存分配失败!" << std::endl;exit(EXIT_FAILURE);}seqQueue.front = seqQueue.rear = 0; // 初始化队列的 front 和 rear 指针
}
3.销毁
// 销毁队列
void destroyQueue(SeqListQueue &seqQueue) {free(seqQueue.base);seqQueue.base = nullptr;seqQueue.front = seqQueue.rear = 0;
}
4.队列是否为空
// 判断队列是否为空
bool isEmptyQueue(SeqListQueue seqQueue) {return seqQueue.front == seqQueue.rear;
}
5.队列长度
// 获取队列长度
int queueLength(SeqListQueue seqQueue) {return (seqQueue.rear - seqQueue.front + MAXQSIZE) % MAXQSIZE;
}
6.清空队列
// 清空队列
void clearQueue(SeqListQueue &seqQueue) {seqQueue.front = seqQueue.rear = 0; // 将 front 和 rear 指针重置为零
}
7.队列头元素
// 获取队列的队首元素
bool getFront(SeqListQueue seqQueue, int &element) {if (seqQueue.front == seqQueue.rear) {std::cerr << "队列为空,无法获取队首元素!" << std::endl;return false;}element = seqQueue.base[seqQueue.front];return true;
}
8.入队
// 入队
bool enQueue(SeqListQueue &seqQueue, int element) {if ((seqQueue.rear + 1) % MAXQSIZE == seqQueue.front) {std::cerr << "队列已满,无法入队!" << std::endl;return false;}seqQueue.base[seqQueue.rear] = element;seqQueue.rear = (seqQueue.rear + 1) % MAXQSIZE;return true;
}
9.出队
// 出队
bool deQueue(SeqListQueue &seqQueue, int &element) {if (seqQueue.front == seqQueue.rear) {std::cerr << "队列为空,无法出队!" << std::endl;return false;}element = seqQueue.base[seqQueue.front];seqQueue.front = (seqQueue.front + 1) % MAXQSIZE;return true;
}
10.完整代码
#include <iostream>
#include <cstdlib> // for malloc, free#define MAXQSIZE 100 // 最大队列长度struct SeqListQueue{int *base;int front;int rear;
};// 队列初始化
void initQueue(SeqListQueue &seqQueue){seqQueue.base = (int *)malloc(sizeof(int) * MAXQSIZE); // 为队列的数组成员分配内存空间if (!seqQueue.base) {std::cerr << "内存分配失败!" << std::endl;exit(EXIT_FAILURE);}seqQueue.front = seqQueue.rear = 0; // 初始化队列的 front 和 rear 指针
}// 入队
bool enQueue(SeqListQueue &seqQueue, int element) {if ((seqQueue.rear + 1) % MAXQSIZE == seqQueue.front) {std::cerr << "队列已满,无法入队!" << std::endl;return false;}seqQueue.base[seqQueue.rear] = element;seqQueue.rear = (seqQueue.rear + 1) % MAXQSIZE;return true;
}// 出队
bool deQueue(SeqListQueue &seqQueue, int &element) {if (seqQueue.front == seqQueue.rear) {std::cerr << "队列为空,无法出队!" << std::endl;return false;}element = seqQueue.base[seqQueue.front];seqQueue.front = (seqQueue.front + 1) % MAXQSIZE;return true;
}// 输出队列元素
void printQueue(SeqListQueue seqQueue) {int i = seqQueue.front;while (i != seqQueue.rear) {std::cout << seqQueue.base[i] << " ";i = (i + 1) % MAXQSIZE;}std::cout << std::endl;
}// 销毁队列
void destroyQueue(SeqListQueue &seqQueue) {free(seqQueue.base);seqQueue.base = nullptr;seqQueue.front = seqQueue.rear = 0;
}// 判断队列是否为空
bool isEmptyQueue(SeqListQueue seqQueue) {return seqQueue.front == seqQueue.rear;
}// 获取队列长度
int queueLength(SeqListQueue seqQueue) {return (seqQueue.rear - seqQueue.front + MAXQSIZE) % MAXQSIZE;
}// 清空队列
void clearQueue(SeqListQueue &seqQueue) {seqQueue.front = seqQueue.rear = 0; // 将 front 和 rear 指针重置为零
}// 获取队列的队首元素
bool getFront(SeqListQueue seqQueue, int &element) {if (seqQueue.front == seqQueue.rear) {std::cerr << "队列为空,无法获取队首元素!" << std::endl;return false;}element = seqQueue.base[seqQueue.front];return true;
}int main() {SeqListQueue seqQueue;initQueue(seqQueue); // 初始化队列// 测试入队for (int i = 1; i <= 5; ++i) {enQueue(seqQueue, i * 10);}// 输出队列元素std::cout << "队列元素:";printQueue(seqQueue);// 获取队首元素int frontElement;if (getFront(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 << "队列元素:";printQueue(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;
}
2.队列的链式存储方式的实现
1.定义
typedef struct QNode {int data; // 元素struct QNode *next; // 指向下一个节点的指针
} QNode, *QueuePtr;typedef struct {QueuePtr front; // 队首指针QueuePtr rear; // 队尾指针
} LinkQueue;
2.队列初始化
// 初始化队列
void initQueue(LinkQueue &link) {link.front = link.rear = (QueuePtr)malloc(sizeof(QNode));if (!link.front) {exit(-1); // 内存分配失败}link.front->next = NULL;
}
3.销毁
void destroyQueue(LinkQueue &queue) {QueuePtr p, q;p = queue.front;while (p) {q = p->next;free(p);p = q;}queue.front = queue.rear = nullptr; // 将队首和队尾指针置为空指针
}
4.队列是否为空
// 判断队列是否为空
bool isEmptyQueue(LinkQueue queue) {return queue.front == queue.rear;
}
5.队列长度
// 获取队列长度
int queueLength(LinkQueue queue) {int length = 0;QueuePtr p = queue.front->next;while (p) {length++;p = p->next;}return length;
}
6.清空队列
// 清空队列
void clearQueue(LinkQueue &queue) {QueuePtr p = queue.front->next;while (p) {QueuePtr temp = p;p = p->next;free(temp);}queue.front->next = nullptr;queue.rear = queue.front;
}
7.队列头元素
// 获取队列的头元素
int getFront(LinkQueue queue) {if (isEmptyQueue(queue)) {cout << "队列为空!" << endl;return -1;}return queue.front->next->data;
}
8.入队
// 入队
void enQueue(LinkQueue &queue, int element) {QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); // 申请内存空间if (!p) {exit(-1); // 内存分配失败}p->data = element;p->next = NULL;queue.rear->next = p;queue.rear = p;
}
9.出队
// 出队
int deQueue(LinkQueue &queue, int &element) {if (queue.rear == queue.front) {return 0; // 队列为空}QueuePtr p = queue.front->next;element = p->data;queue.front->next = p->next;if (queue.rear == p) {queue.rear = queue.front;}free(p);return 1;
}
10.完整代码
#include <iostream>
#include <cstdlib> // for malloc, free
using namespace std;typedef int ElementType;typedef struct QNode {int data; // 元素struct QNode *next; // 指向下一个节点的指针
} QNode, *QueuePtr;typedef struct {QueuePtr front; // 队首指针QueuePtr rear; // 队尾指针
} LinkQueue;// 初始化队列
void initQueue(LinkQueue &link) {link.front = link.rear = (QueuePtr)malloc(sizeof(QNode));if (!link.front) {exit(-1); // 内存分配失败}link.front->next = NULL;
}// 入队
void enQueue(LinkQueue &queue, int element) {QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); // 申请内存空间if (!p) {exit(-1); // 内存分配失败}p->data = element;p->next = NULL;queue.rear->next = p;queue.rear = p;
}// 出队
int deQueue(LinkQueue &queue, int &element) {if (queue.rear == queue.front) {return 0; // 队列为空}QueuePtr p = queue.front->next;element = p->data;queue.front->next = p->next;if (queue.rear == p) {queue.rear = queue.front;}free(p);return 1;
}// 销毁队列
void destroyQueue(LinkQueue &queue) {QueuePtr p, q;p = queue.front;while (p) {q = p->next;free(p);p = q;}queue.front = queue.rear = nullptr; // 将队首和队尾指针置为空指针
}// 清空队列
void clearQueue(LinkQueue &queue) {QueuePtr p = queue.front->next;while (p) {QueuePtr temp = p;p = p->next;free(temp);}queue.front->next = nullptr;queue.rear = queue.front;
}// 判断队列是否为空
bool isEmptyQueue(LinkQueue queue) {return queue.front == queue.rear;
}// 获取队列长度
int queueLength(LinkQueue queue) {int length = 0;QueuePtr p = queue.front->next;while (p) {length++;p = p->next;}return length;
}// 获取队列的头元素
int getFront(LinkQueue queue) {if (isEmptyQueue(queue)) {cout << "队列为空!" << endl;return -1;}return queue.front->next->data;
}// 输出队列元素
void printQueue(LinkQueue queue) {QueuePtr p = queue.front->next;while (p) {cout << p->data << " ";p = p->next;}cout << endl;
}int main() {LinkQueue queue;initQueue(queue); // 初始化队列// 测试入队enQueue(queue, 10);enQueue(queue, 20);enQueue(queue, 30);// 输出队列元素cout << "队列元素:";printQueue(queue);// 测试出队int element;if (deQueue(queue, element)) {cout << "出队元素:" << element << endl;} else {cout << "队列为空,无法出队!" << endl;}// 输出队列元素cout << "队列元素:";printQueue(queue);// 清空队列clearQueue(queue);// 测试是否为空if (isEmptyQueue(queue)) {cout << "队列已清空或为空" << endl;} else {cout << "队列不为空" << endl;}// 测试队列长度cout << "队列长度为:" << queueLength(queue) << endl;// 测试获取队列头元素cout << "队列头元素为:" << getFront(queue) << endl;return 0;
}
3.线性表、栈、队列的区别
相同点:逻辑结构相同,都是线性的;都可以用顺序存储或者链式存储;栈和队列都是两种特殊的线性表,即受限的线性表(知识对插入、删除运算加以限制)。
不同点:
1.运算规则不同
线性表为随机存储,栈只允许在一段进行插入和删除运算,因而是后进先出表LIFO。
队列是只允许在一段进行插入、另一端进行删除操作,因而是先进先出表FIFO。
2.用途不同
线性表比较通用;堆栈用于函数调用、递归和简化设计等;队列用于离散事件模拟、OS作业调度和简化设计等。