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) 高性能实现基础
简洁性 接口简单明了 易于理解和实现
相关推荐
郝学胜-神的一滴6 小时前
深入解析Python字典的继承关系:从abc模块看设计之美
网络·数据结构·python·程序人生
HABuo7 小时前
【linux文件系统】磁盘结构&文件系统详谈
linux·运维·服务器·c语言·c++·ubuntu·centos
颜酱7 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
m0_736919107 小时前
C++代码风格检查工具
开发语言·c++·算法
yugi9878387 小时前
基于MATLAB强化学习的单智能体与多智能体路径规划算法
算法·matlab
DuHz8 小时前
超宽带脉冲无线电(Ultra Wideband Impulse Radio, UWB)简介
论文阅读·算法·汽车·信息与通信·信号处理
Polaris北极星少女8 小时前
TRSV优化2
算法
代码游侠9 小时前
C语言核心概念复习——网络协议与TCP/IP
linux·运维·服务器·网络·算法
2301_763472469 小时前
C++20概念(Concepts)入门指南
开发语言·c++·算法
abluckyboy10 小时前
Java 实现求 n 的 n^n 次方的最后一位数字
java·python·算法