C语言 队列的实现全解析

C语言 队列的实现全解析

什么是队列

队列是一种常见的数据结构,它采用先进先出的方式来管理数据。当我们需要按照时间顺序依次处理一系列任务时,队列便成了一个非常有用的工具。

队列的实现

在C语言中,队列可以通过数组或者链表来实现。当使用数组实现队列时,我们需要定义一个固定大小的数组和两个指针——队头指针head和队尾指针tail。定义如下:

#define QUEUE_SIZE 100

typedef struct {
    int data[QUEUE_SIZE];
    int head, tail;
} Queue;

其中,head指向队列的第一个元素,tail指向队尾元素的下一个位置。初始化队列时,将head和tail均初始化为0即可:

Queue q;
q.head = q.tail = 0; // 初始化队列

队列的操作

接下来我们需要实现队列的四个基本操作——入队、出队、查看队首元素和查看队列大小。

入队

入队操作用来将新的元素添加到队列末尾。如果队列已满,入队操作将无法执行。

int enqueue(Queue *q, int element) {
    if ((q->tail + 1) % QUEUE_SIZE == q->head) {
        return 0; // 队列已满,无法入队
    }
    q->data[q->tail] = element;
    q->tail = (q->tail + 1) % QUEUE_SIZE;
    return 1; // 入队成功
}

如果队列已满,tail指针将指向队列的头部,所以我们使用(q->tail + 1) % QUEUE_SIZE来计算新的tail的位置。

出队

出队操作用来将队列中的第一个元素移除并返回它的值。如果队列为空,出队操作将无法执行。

int dequeue(Queue *q) {
    if (q->head == q->tail) {
        return -1; // 队列为空,无法出队
    }
    int res = q->data[q->head];
    q->head = (q->head + 1) % QUEUE_SIZE;
    return res;
}

查看队首元素

查看队首元素操作用来返回队列中的第一个元素,但不会将其移除。如果队列为空,查看队首元素的操作将返回-1。

int peek(Queue *q) {
    if (q->head == q->tail) {
        return -1; // 队列为空,无队首元素
    }
    return q->data[q->head];
}

查看队列大小

查看队列大小操作用来返回队列中元素的个数。

int size(Queue *q) {
    return (q->tail - q->head + QUEUE_SIZE) % QUEUE_SIZE;
}

示例说明

下面给出两个队列的示例操作。

示例一

假设我们要实现一个循环队列,当队列满时,新来的元素将覆盖队列中原有的元素。

#include <stdio.h>

int main() {
    Queue q;
    q.head = q.tail = 0; // 初始化队列
    int n = 5; // 队列的大小为5
    int i;
    for (i = 0; i < n + 1; i++) {
        enqueue(&q, i);
        printf("enqueue %d\n", i);
    }
    printf("队列的元素个数为 %d\n", size(&q)); // 队列的元素个数为 5
    for (i = 0; i < n; i++) {
        int x = dequeue(&q);
        printf("dequeue %d\n", x);
    }
    printf("队列的元素个数为 %d\n", size(&q)); // 队列的元素个数为 0
    return 0;
}

输出:

enqueue 0
enqueue 1
enqueue 2
enqueue 3
enqueue 4
队列已满,无法入队
队列的元素个数为 5
dequeue 0
dequeue 1
dequeue 2
dequeue 3
dequeue 4
队列的元素个数为 0

示例二

假设我们要通过队列实现一个简单的计算器,读入一系列整数和加减号,并按照之前整数的顺序依次进行加减运算,最后输出结果。

#include <stdio.h>

int main() {
    Queue q;
    q.head = q.tail = 0; // 初始化队列
    int n, res = 0, sign = 1; // sign表示当前数字的符号
    char ch;
    scanf("%d", &n);
    enqueue(&q, n); // 将第一个数字入队
    while ((ch = getchar()) != '\n') { 
        if (ch >= '0' && ch <= '9') {
            n = n * 10 + ch - '0';
        } else {
            res += sign * dequeue(&q); // 将队首元素弹出并加到res中
            enqueue(&q, sign * n); // 将新的数字入队
            sign = (ch == '+') ? 1 : -1; // 根据运算符更新符号
            n = 0; // 清除n,准备读入下一个数字
        }
    }
    res += sign * dequeue(&q); // 将队首元素弹出并加到res中
    printf("计算结果为 %d\n", res);
    return 0;
}

假设输入如下:

10 + 1 - 4 + 3

输出:

计算结果为 10

总结

在本文中,我们通过C语言的数组实现和结构体定义,讲解了队列的操作和实现方式,同时提供了两个队列的例子。作为一种常见的数据结构,队列在程序设计中有着广泛的应用,如线程池、事件处理等,自行练习写队列程序有助于更好地掌握C语言的数据结构和算法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言 队列的实现全解析 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 收集json解析的四种方法分享

    收集JSON解析的四种方法分享 在Web开发中,处理JSON是必不可少的一部分,而JSON解析也是必须要掌握的技能之一。下面分享一些常用的JSON解析方法以及它们的特点,希望对您有所帮助。 使用JavaScript原生解析方法 如果需要解析JSON字符串,可以使用JavaScript中原生提供的JSON.parse方法。该方法将JSON字符串转换为JavaS…

    C 2023年5月23日
    00
  • C中的char s[]和char *s有什么区别

    当我们声明一个字符数组(char array)或一个字符指针(char pointer)时,会用到char s[]和char *s两种写法。它们之间有以下区别: 内存分配方式不同 char s[]声明的是字符数组,也叫数组型字符串(array-style string)。它需要在定义的时候指定初始值,编译器会自动计算数组的大小,将内存分配到栈上,这个数组的大…

    C 2023年5月10日
    00
  • C语言小程序 如何判断三角型类型

    要判断一个三角形的类型,需要先知道这个三角形的三边长度。以下是完整攻略: 首先,需要从用户处获取三角形的三条边长,可以采用以下代码读取用户输入的三边: double a, b, c; scanf("%lf%lf%lf", &a, &b, &c); 接下来,需要判断输入的边长是否可以组成三角形。可以用以下代码来实现:…

    C 2023年5月23日
    00
  • jQuery访问json文件中数据的方法示例

    关于“jQuery访问json文件中数据的方法示例”的完整攻略,我提供如下说明。 标题 1. 创建json文件 首先要创建一个json文件,可以使用任何文本编辑器,比如sublime、notepad++等等。文件后缀名为.json 2. 读取json文件 读取json文件需要ajax方法。使用jQuery中的 $.getJSON() 方法,可用参数type、…

    C 2023年5月23日
    00
  • C/C++ 单元自动化测试解决方案总结

    C/C++ 单元自动化测试解决方案总结 背景 C/C++ 是一门常用的编程语言,广泛应用于嵌入式系统、操作系统、游戏等领域。在实际的开发过程中,单元测试是必不可少的环节,可以确保代码的质量和稳定性。 常用的单元测试框架 C/C++ 的单元测试框架有很多,包括 Google Test,CppUnit,Boost.Test 等。这些框架可以满足大部分的单元测试需…

    C 2023年5月23日
    00
  • c++ 面向对象的类设计

    C++ 面向对象的类设计攻略 什么是面向对象的类设计 面向对象的类设计是指基于面向对象编程思想来设计类的过程。面向对象编程思想是一种编程范式,其中的对象是一个实例或者说是类的一个实例化对象,这些对象通过类之间的消息传递进行通信,从而共同完成一个复杂的任务。 在C++编程中,面向对象的类设计尤为重要,因为它是C++中的重要组成部分。经典的面向对象编程思想是将数…

    C 2023年5月22日
    00
  • 对C语言中递归算法的深入解析

    对C语言中递归算法的深入解析 什么是递归算法 递归算法是指函数自身调用自身的算法。递归优雅而简洁,但一定要写得正确,否则会造成很多问题。 递归算法的基本原理 递归函数包含两个部分: 基本情况,也称为递归终止条件。它告诉函数何时停止递归。 递推部分,也称为递归体。它包含所有的递归逻辑,将问题逐步分解直至达到基本情况。 递归算法示例说明 示例一:斐波那契数列 i…

    C 2023年5月22日
    00
  • C语言中炫酷的文件操作实例详解

    C语言中炫酷的文件操作实例详解 为什么文件操作很重要? 文件操作是C语言开发必不可少的一部分。在C语言中,文件可以被用作数据存储和读取,以便在程序中传递和处理数据。这使得文件操作成为C语言中最重要的基础和必备知识之一。 文件操作的基本概念 C语言中,文件可以被看做一个sequence of bytes。C语言操作文件主要基于以下三个基本概念: 文件指针:文件…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部