首页 > 其他分享 >队列的用法详解

队列的用法详解

时间:2024-11-05 13:47:37浏览次数:4  
标签:return 队列 用法 queue int 详解 front rear

队列是一种常用的数据结构,具有先进先出(FIFO, First-In-First-Out)的特点。通常用来管理需要按顺序处理的任务,例如打印队列、任务调度、资源分配等。下面详细介绍队列的基本概念、常用操作、类型及其在C语言中的实现。

队列的基本概念

在队列中:

  • 入队 (enqueue):将元素添加到队列的尾部。
  • 出队 (dequeue):从队列的头部移除元素。
  • 队头 (front):指向队列第一个元素的指针或索引。
  • 队尾 (rear):指向队列最后一个元素的指针或索引。

队列的常见类型

  1. 普通队列

    • 先进先出(FIFO)顺序,元素只能从尾部入队,从头部出队。
  2. 循环队列

    • 队列空间循环利用,队尾达到数组末尾时会循环至队列头部。
  3. 双端队列 (Deque)

    • 允许在两端进行入队和出队操作。
  4. 优先队列

    • 元素带有优先级,出队时优先级高的元素先出队,而不是按入队顺序出队。

队列的常用操作

以下是队列的基本操作及其描述:

  • 初始化队列:创建一个空队列。
  • 判断队列是否为空:检查队列是否有元素。
  • 判断队列是否满(对于数组实现的固定大小队列)。
  • 入队:将元素添加到队尾。
  • 出队:移除队头的元素。
  • 获取队头元素:查看队头元素但不移除它。
  • 获取队列长度:返回队列中的元素个数。

队列的实现方法

1. 数组实现普通队列

普通队列可以用固定大小的数组实现,但缺点是数组空间不能重复利用。每次出队,队列头指针向后移动一位,可能导致尾部的空闲空间无法使用。

#include <stdio.h>
#include <stdlib.h>
#define MAX 5

typedef struct Queue {
    int data[MAX];
    int front;  // 队头索引
    int rear;   // 队尾索引
} Queue;

// 初始化队列
Queue* initializeQueue() {
    Queue* queue = (Queue*)malloc(sizeof(Queue));
    queue->front = -1;
    queue->rear = -1;
    return queue;
}

// 判断队列是否为空
int isEmpty(Queue* queue) {
    return queue->front == -1;
}

// 判断队列是否满
int isFull(Queue* queue) {
    return queue->rear == MAX - 1;
}

// 入队
void enqueue(Queue* queue, int value) {
    if (isFull(queue)) {
        printf("队列已满\n");
        return;
    }
    if (isEmpty(queue)) {
        queue->front = 0;
    }
    queue->data[++queue->rear] = value;
    printf("入队:%d\n", value);
}

// 出队
int dequeue(Queue* queue) {
    if (isEmpty(queue)) {
        printf("队列为空\n");
        return -1;
    }
    int value = queue->data[queue->front];
    if (queue->front == queue->rear) {
        // 队列变空
        queue->front = queue->rear = -1;
    } else {
        queue->front++;
    }
    printf("出队:%d\n", value);
    return value;
}

// 获取队头元素
int peekFront(Queue* queue) {
    if (isEmpty(queue)) {
        printf("队列为空\n");
        return -1;
    }
    return queue->data[queue->front];
}
2. 循环队列

循环队列利用“环形”数组解决了普通队列不能重复利用空间的问题。队列的尾部超过数组末尾时,会绕到数组开头继续填充

  • 队满判断条件:(rear + 1) % MAX == front
  • 队空判断条件:front == -1
    #define MAX 5
    
    typedef struct CircularQueue {
        int data[MAX];
        int front;
        int rear;
    } CircularQueue;
    
    // 初始化循环队列
    CircularQueue* initializeCircularQueue() {
        CircularQueue* queue = (CircularQueue*)malloc(sizeof(CircularQueue));
        queue->front = -1;
        queue->rear = -1;
        return queue;
    }
    
    // 判断队列是否为空
    int isCircularEmpty(CircularQueue* queue) {
        return queue->front == -1;
    }
    
    // 判断队列是否满
    int isCircularFull(CircularQueue* queue) {
        return (queue->rear + 1) % MAX == queue->front;
    }
    
    // 入队
    void enqueueCircular(CircularQueue* queue, int value) {
        if (isCircularFull(queue)) {
            printf("循环队列已满\n");
            return;
        }
        if (isCircularEmpty(queue)) {
            queue->front = 0;
        }
        queue->rear = (queue->rear + 1) % MAX;
        queue->data[queue->rear] = value;
        printf("循环队列入队:%d\n", value);
    }
    
    // 出队
    int dequeueCircular(CircularQueue* queue) {
        if (isCircularEmpty(queue)) {
            printf("循环队列为空\n");
            return -1;
        }
        int value = queue->data[queue->front];
        if (queue->front == queue->rear) {
            // 队列变空
            queue->front = queue->rear = -1;
        } else {
            queue->front = (queue->front + 1) % MAX;
        }
        printf("循环队列出队:%d\n", value);
        return value;
    }
    
    // 获取队头元素
    int peekCircularFront(CircularQueue* queue) {
        if (isCircularEmpty(queue)) {
            printf("循环队列为空\n");
            return -1;
        }
        return queue->data[queue->front];
    }
    
    3. 链表实现队列

    链表实现的队列不受固定大小限制,动态内存分配适用于队列大小不固定的情况。

    typedef struct Node {
        int data;
        struct Node* next;
    } Node;
    
    typedef struct LinkedQueue {
        Node* front;
        Node* rear;
    } LinkedQueue;
    
    // 初始化链表队列
    LinkedQueue* initializeLinkedQueue() {
        LinkedQueue* queue = (LinkedQueue*)malloc(sizeof(LinkedQueue));
        queue->front = queue->rear = NULL;
        return queue;
    }
    
    // 判断队列是否为空
    int isLinkedQueueEmpty(LinkedQueue* queue) {
        return queue->front == NULL;
    }
    
    // 入队
    void enqueueLinked(LinkedQueue* queue, int value) {
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->data = value;
        newNode->next = NULL;
        if (isLinkedQueueEmpty(queue)) {
            queue->front = queue->rear = newNode;
        } else {
            queue->rear->next = newNode;
            queue->rear = newNode;
        }
        printf("链表队列入队:%d\n", value);
    }
    
    // 出队
    int dequeueLinked(LinkedQueue* queue) {
        if (isLinkedQueueEmpty(queue)) {
            printf("链表队列为空\n");
            return -1;
        }
        Node* temp = queue->front;
        int value = temp->data;
        queue->front = queue->front->next;
        if (queue->front == NULL) {
            queue->rear = NULL;
        }
        free(temp);
        printf("链表队列出队:%d\n", value);
        return value;
    }
    
    // 获取队头元素
    int peekLinkedFront(LinkedQueue* queue) {
        if (isLinkedQueueEmpty(queue)) {
            printf("链表队列为空\n");
            return -1;
        }
        return queue->front->data;
    }
    

    队列的应用场景

  • 操作系统的任务调度:使用队列管理任务,使其按顺序执行。
  • 图的广度优先搜索 (BFS):用队列记录访问节点顺序。
  • 打印队列:将待打印的文件按请求顺序排入队列。
  • 网络流量管理:数据包按到达顺序排入队列,依次处理。

标签:return,队列,用法,queue,int,详解,front,rear
From: https://blog.csdn.net/kuixiang_yin/article/details/143427423

相关文章

  • Nuxt.js 应用中的 nitro:build:public-assets 事件钩子详解
    title:Nuxt.js应用中的nitro:build:public-assets事件钩子详解date:2024/11/5updated:2024/11/5author:cmdragonexcerpt:nitro:build:public-assets是Nuxt3中的一个生命周期钩子,在复制公共资产之后调用。该钩子使开发者能够在构建Nitro服务器之前,对公共资产进......
  • 热更新技术详解
    1.引言1.1热更新的定义热更新是一种技术手段,允许在不重启应用程序的情况下更新和替换应用中的代码、资源或配置。这种技术通常在需要频繁更新、提高用户体验的系统中使用,如Web应用、移动应用和游戏开发等场景。通过热更新,开发者可以在用户使用过程中修复BUG、推送新功能......
  • 【Linux】进程间通信(命名管道、共享内存、消息队列、信号量)
                                 作者主页:   作者主页                           本篇博客专栏:Linux                ......
  • Linux常用命令——su 命令详解
    Linux常用命令——su命令详解命令介绍:su命令在Linux系统中用于切换用户身份。它是系统管理员和高级用户常用的命令,支持多种选项来控制身份切换过程。基本语法:su[选项][用户名]常用选项和参数:-:切换到指定用户并加载该用户的环境变量,类似于重新登录。示例:su-......
  • Linux常用命令——sed 命令详解
    Linux常用命令——sed命令详解命令介绍:sed(streameditor)是一种强大的文本处理工具,在Linux系统中广泛用于对文件进行过滤和转换。sed可以对文件中的文本进行插入、删除、查找和替换等操作。基本语法:sed[选项]'命令'文件常用选项和参数:无参数:简单替换。示例:1......
  • Linux常用命令——du 命令详解
    Linux常用命令——du命令详解命令介绍:du命令在Linux系统中用于显示文件和目录的磁盘使用情况。它非常有用,可以帮助用户了解每个文件和目录占用的空间。基本语法:du[选项][文件或目录]常用选项和参数:-a,--all:不仅显示目录的磁盘使用情况,还显示所有文件的磁盘......
  • Linux常用命令——mount 命令详解
    Linux常用命令——mount命令详解命令介绍:mount命令在Linux系统中用于将文件系统挂载到指定的目录。它是系统管理中非常重要的命令之一,支持多种参数选项。基本语法:mount[选项]设备文件夹常用选项和参数:-t,--types:指定要挂载的文件系统类型,如ext4、vfat、nt......
  • iostat命令详解
    iostat用于输出CPU和磁盘I/O相关的统计信息. 1.不加选项执行iostat [patrickxu@vm1~]$iostatLinux2.6.32-279.19.3.el6.ucloud.x86_64(vm1)  06/11/2017 _x86_64_   (8CPU)avg-cpu: %user  %nice%system%iowait %steal  %idle        ......
  • 详解 QTcpServer
    QTcpServer是Qt网络模块中用于创建TCP服务器的类。它负责接受客户端的连接并为每个连接创建相应的QTcpSocket对象。以下是对QTcpServer的详细说明,包括其功能、用法以及常用的信号和槽。主要功能监听连接:QTcpServer可以在指定的地址和端口上监听传入的TCP连接......
  • Neo4j入门:详解Cypher查询语言中的MATCH语句
    Neo4j入门:详解Cypher查询语言中的MATCH语句引言什么是MATCH语句?示例数据1.基础节点查询查询所有节点按标签查询节点2.关系查询基础关系查询指定关系方向指定关系类型3.使用WHERE子句4.使用参数5.多重MATCH和WITH子句实用技巧总结引言大家好!今天我们来学习Neo......