Linux环境下的C语言编程(三十九)

三、队列的基本操作(接三十八)

1. 基本数据结构定义

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAX_SIZE 100  // 队列最大容量

// 队列结构体定义
typedef struct {
    int data[MAX_SIZE];  // 存储数据的数组
    int front;           // 队头指针
    int rear;            // 队尾指针
    int size;            // 当前队列大小
} Queue;

二、队列基本操作实现

1. 初始化队列

复制代码
// 初始化队列
void initQueue(Queue* q) {
    q->front = 0;    // 队头指针初始化为0
    q->rear = -1;    // 队尾指针初始化为-1(表示空队列)
    q->size = 0;     // 队列大小为0
}

2. 判断队列是否为空

复制代码
// 检查队列是否为空
bool isEmpty(Queue* q) {
    // 方法1:使用size变量
    return q->size == 0;
    
    // 方法2:使用front和rear指针(循环队列)
    // return (q->front == (q->rear + 1) % MAX_SIZE);
}

3. 判断队列是否已满

复制代码
// 检查队列是否已满
bool isFull(Queue* q) {
    // 方法1:使用size变量
    return q->size == MAX_SIZE;
    
    // 方法2:使用front和rear指针(循环队列)
    // return ((q->rear + 2) % MAX_SIZE == q->front);
}

4. 入队操作

复制代码
// 将元素添加到队列尾部
bool enqueue(Queue* q, int value) {
    if (isFull(q)) {
        printf("错误:队列已满,无法添加元素 %d\n", value);
        return false;  // 入队失败
    }
    
    // 移动rear指针(循环队列)
    q->rear = (q->rear + 1) % MAX_SIZE;
    
    // 在rear位置插入元素
    q->data[q->rear] = value;
    
    // 队列大小增加
    q->size++;
    
    printf("成功入队: %d (位置: %d)\n", value, q->rear);
    return true;  // 入队成功
}

5. 出队操作

复制代码
// 从队列头部移除元素
bool dequeue(Queue* q, int* value) {
    if (isEmpty(q)) {
        printf("错误:队列为空,无法移除元素\n");
        return false;  // 出队失败
    }
    
    // 获取队头元素
    *value = q->data[q->front];
    
    // 移动front指针(循环队列)
    q->front = (q->front + 1) % MAX_SIZE;
    
    // 队列大小减少
    q->size--;
    
    printf("成功出队: %d (新队头位置: %d)\n", *value, q->front);
    return true;  // 出队成功
}

6. 查看队头元素

复制代码
// 获取队头元素但不移除
bool peekFront(Queue* q, int* value) {
    if (isEmpty(q)) {
        printf("错误:队列为空,无队头元素\n");
        return false;
    }
    
    *value = q->data[q->front];
    printf("队头元素: %d\n", *value);
    return true;
}

7. 查看队尾元素

复制代码
// 获取队尾元素但不移除
bool peekRear(Queue* q, int* value) {
    if (isEmpty(q)) {
        printf("错误:队列为空,无队尾元素\n");
        return false;
    }
    
    *value = q->data[q->rear];
    printf("队尾元素: %d\n", *value);
    return true;
}

8. 获取队列大小

复制代码
// 返回队列中元素的数量
int getSize(Queue* q) {
    return q->size;
    
    // 如果不使用size变量,可以用以下公式计算:
    // return (q->rear - q->front + MAX_SIZE) % MAX_SIZE + 1;
}

9. 清空队列

复制代码
// 清空队列中的所有元素
void clearQueue(Queue* q) {
    q->front = 0;
    q->rear = -1;
    q->size = 0;
    printf("队列已清空\n");
}

三、完整的队列操作示例

复制代码
// 打印队列内容
void printQueue(Queue* q) {
    if (isEmpty(q)) {
        printf("队列为空\n");
        return;
    }
    
    printf("队列内容 (从队头到队尾): ");
    
    if (q->front <= q->rear) {
        // 正常情况:front <= rear
        for (int i = q->front; i <= q->rear; i++) {
            printf("%d ", q->data[i]);
        }
    } else {
        // 循环情况:rear < front
        for (int i = q->front; i < MAX_SIZE; i++) {
            printf("%d ", q->data[i]);
        }
        for (int i = 0; i <= q->rear; i++) {
            printf("%d ", q->data[i]);
        }
    }
    printf("\n");
}

// 显示队列状态
void displayQueueStatus(Queue* q) {
    printf("\n=== 队列状态 ===\n");
    printf("队头位置: %d\n", q->front);
    printf("队尾位置: %d\n", q->rear);
    printf("队列大小: %d\n", getSize(q));
    printf("队列容量: %d\n", MAX_SIZE);
    printf("是否为空: %s\n", isEmpty(q) ? "是" : "否");
    printf("是否已满: %s\n", isFull(q) ? "是" : "否");
    printQueue(q);
}

// 主函数:测试队列基本操作
int main() {
    Queue myQueue;
    int value;
    
    printf("=== 队列基本操作演示 ===\n");
    
    // 1. 初始化队列
    printf("\n1. 初始化队列\n");
    initQueue(&myQueue);
    displayQueueStatus(&myQueue);
    
    // 2. 入队操作
    printf("\n2. 入队操作演示\n");
    printf("入队元素: 10, 20, 30, 40, 50\n");
    enqueue(&myQueue, 10);
    enqueue(&myQueue, 20);
    enqueue(&myQueue, 30);
    enqueue(&myQueue, 40);
    enqueue(&myQueue, 50);
    displayQueueStatus(&myQueue);
    
    // 3. 查看队头和队尾
    printf("\n3. 查看队头和队尾\n");
    peekFront(&myQueue, &value);
    peekRear(&myQueue, &value);
    
    // 4. 出队操作
    printf("\n4. 出队操作演示\n");
    dequeue(&myQueue, &value);
    printf("出队元素: %d\n", value);
    dequeue(&myQueue, &value);
    printf("出队元素: %d\n", value);
    displayQueueStatus(&myQueue);
    
    // 5. 获取队列大小
    printf("\n5. 获取队列大小\n");
    printf("当前队列大小: %d\n", getSize(&myQueue));
    
    // 6. 继续入队
    printf("\n6. 继续入队操作\n");
    printf("入队元素: 60, 70, 80\n");
    enqueue(&myQueue, 60);
    enqueue(&myQueue, 70);
    enqueue(&myQueue, 80);
    displayQueueStatus(&myQueue);
    
    // 7. 批量出队
    printf("\n7. 批量出队直到队列为空\n");
    while (!isEmpty(&myQueue)) {
        dequeue(&myQueue, &value);
        printf("出队: %d, 剩余大小: %d\n", value, getSize(&myQueue));
    }
    displayQueueStatus(&myQueue);
    
    // 8. 测试边界情况
    printf("\n8. 测试边界情况\n");
    printf("从空队列出队: ");
    dequeue(&myQueue, &value);  // 应该失败
    
    printf("查看空队列的队头: ");
    peekFront(&myQueue, &value);  // 应该失败
    
    // 9. 清空队列
    printf("\n9. 清空队列\n");
    clearQueue(&myQueue);
    displayQueueStatus(&myQueue);
    
    return 0;
}

3. 操作的正式定义

操作 函数名 参数 返回值 说明
初始化 initQueue() Queue指针 void 初始化队列
判空 isEmpty() Queue指针 bool 检查队列是否为空
判满 isFull() Queue指针 bool 检查队列是否已满
入队 enqueue() Queue指针, 元素值 bool 元素添加到队尾
出队 dequeue() Queue指针, 接收指针 bool 移除队头元素
查看队头 peekFront() Queue指针, 接收指针 bool 获取队头元素
查看队尾 peekRear() Queue指针, 接收指针 bool 获取队尾元素
获取大小 getSize() Queue指针 int 返回元素数量
清空队列 clearQueue() Queue指针 void 清空所有元素

四、状态转换图

复制代码
        初始状态
            ↓
       [空队列] (isEmpty = true)
            ↓ Enqueue(x)
      [队列: x] (size = 1)
            ↓ Enqueue(y)
    [队列: x ← y] (size = 2)
            ↓ Dequeue() → 返回x
      [队列: y] (size = 1)
            ↓ Dequeue() → 返回y
       [空队列] (isEmpty = true)
            ↓ Dequeue()
    [错误/异常:队列为空]

五、关键特性总结

特性 描述 重要性
顺序性 元素保持严格的入队顺序 确保公平性
有限访问 只能访问队头和队尾 保证数据完整性
动态性 大小随操作变化 适应不同场景需求
效率 基本操作都是O(1) 高性能实现基础
简洁性 接口简单明了 易于理解和实现
相关推荐
Navigator_Z3 小时前
LeetCode //C - 1289. Minimum Falling Path Sum II
c语言·算法·leetcode
CCblandy3 小时前
令牌桶在 0.9 倍负载超发 19%、固定窗口边界放行 20 个:四种限流算法同构实测
后端·python·算法·性能优化·架构
himobrinehacken3 小时前
取模运算的汇编奥秘揭秘
c语言·安全
mmmmath_33 小时前
LeetCode.104.二叉树的最大深度
数据结构·leetcode
YangYang9YangYan4 小时前
2027供应链计划校招:数学与应用数学专业如何把预测模型讲成业务决策?
人工智能·sql·算法
jsjzsl24 小时前
递归自改进系统(RSI)的本质是自发对称破缺:智能爆炸有界—— AI研发切记盲目投入
人工智能·python·算法
程序员清风4 小时前
最短路径算法:BFS、Dijkstra 与 Floyd
java·算法·宽度优先
梦帮科技4 小时前
Kali Linux Scapy 畸形报文构造学——深度解剖非法 TCP Flags 与反常序列号
linux·爬虫·神经网络·算法·数学建模·系统架构·模拟退火算法
171320330计算机毕设编程6 小时前
计算机毕业设计 基于YOLO改进算法的车辆特征识别系统设计与实现--lw
java·大数据·python·sql·算法