跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C算法

队列详解:从概念到 C 语言实战

队列作为先进先出的线性结构,广泛应用于任务调度、缓冲处理及广度优先搜索等场景。深入解析队列核心操作,包括初始化、入队出队及判空销毁。通过 C 语言分别演示顺序队列(循环数组)与链式队列的实现细节,对比两者在空间占用、溢出处理及性能上的差异,帮助开发者根据实际数据量动态变化需求选择合适的存储方案。

人间失格发布于 2026/3/22更新于 2026/9/346 浏览
队列详解:从概念到 C 语言实战

一、队列的基本概念

队列是一种**先进先出(FIFO,First In First Out)**的线性数据结构。它只允许在队尾进行插入操作,在队头进行删除操作。

生活中常见的队列场景包括银行窗口排队、打印机任务队列以及消息传递等。理解这一结构是掌握更复杂算法的基础。

二、队列的核心操作

要实现一个可用的队列,我们需要关注以下几个核心接口:

  1. 初始化(InitQueue):创建一个空队列,分配必要的内存。
  2. 入队(EnQueue):将新元素添加到队尾。
  3. 出队(DeQueue):移除并返回队头元素。
  4. 获取队头元素(GetFront):查看队头数据但不移除。
  5. 判空(IsEmpty):检查队列是否没有元素。
  6. 销毁(DestroyQueue):释放队列占用的所有内存资源。

三、C 语言实现队列

3.1 顺序队列(数组实现)

顺序队列使用数组存储元素,通过 front 和 rear 指针标记边界。为了避免'假溢出'问题,我们通常采用循环队列的方式,即当指针到达数组末尾时回到开头。

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

// 顺序队列结构体
typedef struct {
    int data[MAX_SIZE];
    int front; // 队头指针(指向队头元素)
    int rear;  // 队尾指针(指向队尾元素的下一个位置)
} SeqQueue;

// 初始化队列
void InitQueue(SeqQueue *q) {
    q->front = 0;
    q->rear = 0;
}

// 判空
int IsEmpty(SeqQueue *q) {
    return q->front == q->rear;
}

// 判满
int IsFull(SeqQueue *q) {
    // 预留一个空间区分空满
     (q->rear + ) % MAX_SIZE == q->front;
}


  {
     (IsFull(q)) {
        ();
         ;
    }
    q->data[q->rear] = value;
    q->rear = (q->rear + ) % MAX_SIZE;
     ;
}


  {
     (IsEmpty(q)) {
        ();
         ;
    }
    *value = q->data[q->front];
    q->front = (q->front + ) % MAX_SIZE;
     ;
}


  {
     (IsEmpty(q)) {
        ();
         ;
    }
    *value = q->data[q->front];
     ;
}


  {
    SeqQueue q;
    InitQueue(&q);

    
    EnQueue(&q, );
    EnQueue(&q, );
    EnQueue(&q, );

    
     frontVal;
    GetFront(&q, &frontVal);
    (, frontVal); 

    
     deVal;
    DeQueue(&q, &deVal);
    (, deVal); 

    
    GetFront(&q, &frontVal);
    (, frontVal); 

     ;
}
return
1
// 入队
int
EnQueue
(SeqQueue *q, int value)
if
printf
"队列已满,无法入队\n"
return
0
1
return
1
// 出队
int
DeQueue
(SeqQueue *q, int *value)
if
printf
"队列为空,无法出队\n"
return
0
1
return
1
// 获取队头元素
int
GetFront
(SeqQueue *q, int *value)
if
printf
"队列为空,无队头元素\n"
return
0
return
1
// 测试顺序队列
int
main
()
// 入队操作
10
20
30
// 获取队头元素
int
printf
"队头元素:%d\n"
// 输出:10
// 出队操作
int
printf
"出队元素:%d\n"
// 输出:10
// 再次获取队头
printf
"新队头元素:%d\n"
// 输出:20
return
0

顺序队列特点:

  • 优点:实现简单,访问速度快,内存连续。
  • 缺点:容量固定,存在'假溢出'问题(需通过循环队列优化)。
3.2 链式队列(链表实现)

链式队列使用链表存储元素,队头指针指向头节点,队尾指针指向尾节点。这种方式不需要预先分配固定大小的内存。

#include <stdio.h>
#include <stdlib.h>

// 节点结构体
typedef struct Node {
    int data;
    struct Node *next;
} Node;

// 链式队列结构体
typedef struct {
    Node *front; // 队头指针(指向头节点)
    Node *rear;  // 队尾指针(指向尾节点)
} LinkQueue;

// 初始化队列
void InitQueue(LinkQueue *q) {
    // 创建头节点(不存储数据)
    Node *head = (Node *)malloc(sizeof(Node));
    head->next = NULL;
    q->front = head;
    q->rear = head;
}

// 判空
int IsEmpty(LinkQueue *q) {
    return q->front == q->rear;
}

// 入队
void EnQueue(LinkQueue *q, int value) {
    // 创建新节点
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->data = value;
    newNode->next = NULL;

    // 插入到队尾
    q->rear->next = newNode;
    q->rear = newNode;
}

// 出队
int DeQueue(LinkQueue *q, int *value) {
    if (IsEmpty(q)) {
        printf("队列为空,无法出队\n");
        return 0;
    }
    Node *temp = q->front->next; // 待删除节点
    *value = temp->data;
    q->front->next = temp->next;

    // 如果删除的是最后一个节点,需更新队尾指针
    if (q->rear == temp) {
        q->rear = q->front;
    }
    free(temp); // 释放节点内存
    return 1;
}

// 获取队头元素
int GetFront(LinkQueue *q, int *value) {
    if (IsEmpty(q)) {
        printf("队列为空,无队头元素\n");
        return 0;
    }
    *value = q->front->next->data;
    return 1;
}

// 销毁队列
void DestroyQueue(LinkQueue *q) {
    while (q->front != NULL) {
        q->rear = q->front->next;
        free(q->front);
        q->front = q->rear;
    }
}

// 测试链式队列
int main() {
    LinkQueue q;
    InitQueue(&q);

    // 入队
    EnQueue(&q, 100);
    EnQueue(&q, 200);
    EnQueue(&q, 300);

    // 获取队头
    int frontVal;
    GetFront(&q, &frontVal);
    printf("队头元素:%d\n", frontVal); // 输出:100

    // 出队
    int deVal;
    DeQueue(&q, &deVal);
    printf("出队元素:%d\n", deVal); // 输出:100

    // 销毁队列
    DestroyQueue(&q);
    return 0;
}

链式队列特点:

  • 优点:容量动态扩展,不存在溢出问题。
  • 缺点:需要额外空间存储指针,操作稍复杂,内存碎片风险。

四、队列的应用场景

  1. 广度优先搜索(BFS):在二叉树层次遍历、图的遍历中常用队列来管理待访问节点。
  2. 缓冲处理:如键盘输入缓冲、网络数据接收缓冲,用于平滑数据流。
  3. 任务调度:操作系统中的进程调度、线程池任务调度,保证公平性。
  4. 消息传递:分布式系统中的消息队列(如 RabbitMQ),解耦生产者与消费者。

五、两种实现的对比选择

场景推荐实现理由
已知数据量且固定顺序队列效率更高,无需额外指针开销
数据量动态变化链式队列避免空间浪费和溢出问题
频繁插入删除链式队列操作更高效(O(1) 时间复杂度)
对内存使用敏感顺序队列内存连续分配,缓存利用率高

目录

  1. 一、队列的基本概念
  2. 二、队列的核心操作
  3. 三、C 语言实现队列
  4. 3.1 顺序队列(数组实现)
  5. 3.2 链式队列(链表实现)
  6. 四、队列的应用场景
  7. 五、两种实现的对比选择

更多推荐文章

查看全部
  • VSCode Copilot 登录失败常见原因与解决方案
  • Chromium 144 Windows 编译指南:Git 安装与配置
  • llama.cpp 实战指南:在普通电脑上运行大模型
  • 基于SSM和Vue的在线投稿系统设计与实现
  • Python 数据分析:数据预处理核心方法
  • Hadoop HDFS 核心机制与设计理念
  • JavaScript 系统对话框实战:alert、confirm 与 prompt 用法解析
  • Python 爬虫获取懂车帝新能源汽车近一年销量榜
  • 初识 AI 语言大模型:概念、能力与挑战
  • ChatGPT 核心功能与高级使用技巧指南
  • OpenClaw 架构解析:单进程设计与插件化扩展
  • 基于 Docker、Playwright 与 Jenkins 的 Web 自动化测试实践
  • AI 编程工具选型:Copilot、Cursor、Codex 核心差异
  • 通义灵码使用教程:从安装到实战,提升 AI 编程效率
  • 零暴露公网 IP 访问本地 AI 服务的方法与数据隐私保护
  • 基于 Spring Boot 与 Vue 框架的软考学习与交流系统设计
  • VS Code + WSL 下 GitHub 访问不稳定及 Copilot 卡顿解决方案
  • 接入第三方 OpenAI 兼容模型到 GitHub Copilot
  • 使用 Web Unlocker 和 n8n 构建自动化资讯系统
  • Spring Cloud 优雅实现远程调用 - OpenFeign

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online