S9 顺序队列
4.1顺序队列
4.1.1队列结构定义分析
#define MAX_SIZE 10typedef struct sqQueue {int data[MAX_SIZE]; // 存储数组int front; // 队头指针int rear; // 队尾指针} sqQueue;关键特性:
- 数组存储:使用固定大小的数组存储队列元素
- 双指针管理:front指向队头元素,rear指向队尾的下一个位置
- 线性增长:指针只增不减,可能导致"假溢出"
4.1.2函数详细讲解与问题分析
1. 初始化函数 ( InitQue ue )
void InitQueue(sqQueue* q) {assert(q != NULL);q->front = 0;q->rear = 0;}代码解读:
- 正确初始化front和rear为0
- 空队列条件: front = = rear
- 符合顺序队列的基本初始化逻辑
2. 队列长度计算 ( QueueLe ngth )
int QueueLength(sqQueue* q) {assert(q != NULL);return q->rear - q->front;}关键点:
- 逻辑正确:rear - front就是元素个数
- 时间复杂度O(1),效率很高
- 这是顺序队列的标准长度计算方法
3. 入队操作 ( Enqueue )
bool Enqueue(sqQueue* q, int e) {assert(q != NULL);if(queuefull(q)) return false;q->data[q->rear] = e;q->rear++;return true;}代码解读:
- 先检查队列是否已满
- 在rear位置插入新元素,然后rear指针后移
- 这是标准的入队操作逻辑
存在问题:
- 没有处理"假溢出":当rear达到MAX_SIZE但front>0时,实际上还有空间可用
- 这是顺序队列的主要缺陷
4. 出队操作 ( Dequeue )
bool Dequeue(sqQueue* q, int* e) {assert(q != NULL);if(queueempty(q)) return false;*e = q->data[q->front];memmove(q->data + q->front, q->data + q->front + 1,(q->rear - q->front - 1) * sizeof(int));q->rear--;return true;}5. 判空与判满函数
判空函数 ( queueem pty )
bool queueempty(sqQueue* q) {assert(q != NULL);if (q->front == q->rear) return true;return false;}关键点:
- 判断逻辑正确: front = = rear 表示队列为空
- 这是队列为空的标准判断条件
判满函数 ( queuefu ll )bool queuefull(sqQueue* q) {assert(q != NULL);return (q->rear == MAX_SIZE);// 更准确的判断:return (q->rear == MAX_SIZE && q->front == 0);}6. 获取队头元素 ( Gethead )
bool Gethead(sqQueue* q, int* e) {assert(q != NULL);if(queueempty(q)) return false;*e = q->data[q->front];return true;}关键点:
- 逻辑正确:获取front位置的元素但不删除
- 时间复杂度O(1),符合队列操作要求
- 这是标准的获取队头元素方法
7. 打印函数 ( printf_ t )
正确实现:
void printf_t(sqQueue* q) {assert(q != NULL);for (int i = q->front; i < q->rear; i++) {printf("%d ", q->data[i]);}}4.1.3总结
时间复杂度总结
操作 | 你的实现 | 改进实现 | 标准要求 |
|---|---|---|---|
入队 | O(1) | O(1) | O(1) |
出队 | O(n) | O(1) | O(1) |
获取队头 | O(1) | O(1) | O(1) |
判空/判满 | O(1) | O(1) | O(1) |
学习建议
- 掌握循环队列:这是解决顺序队列假溢出问题的标准方案
- 理解队列本质:队列是FIFO结构,操作应该高效
- 注重算法复杂度:基础操作应该保持O(1)时间复杂度
- 实践动态扩容:学习如何实现队列的动态扩容机制
你的代码基本体现了顺序队列的概念,但需要重点改进出队操作的性能问题和实现循环队列来解决假溢出。掌握这些改进后,你对队列数据结构的理解会更加深入。 队列元素操作有关函数,包括add、remove、element、offer、poll、peek、put、get等基本操作。: 顺序队列的表示方法,使用一维数组存储,front和rear指针分别指示队头和队尾元素的位置。: 顺序队列中的"假上溢"现象,由于入队和出队操作中头尾指针只增加不减小,致使被删元素的空间无法重新利用。: 循环队列的判空和判满条件,队列判空的条件是front=rear,而队列判满的条件是front=(rear+1)%MaxSize。
