十、数据结构——链式队列

数据结构中的链式队列

目录

一、链式队列的定义
二、链式队列的实现
三、链式队列的基本操作

  • ①初始化
    ②判空
    ③入队
    ④出队
    ⑤获取长度
    ⑥打印

四、循环队列的应用
五、总结
六、全部代码
七、结果

在数据结构中,队列(Queue)是一种常见的线性数据结构,遵循先进先出(First In First Out,FIFO)的原则。链式队列是队列的一种实现方式,它使用链表来存储队列中的元素。本篇博客将详细介绍链式队列的定义、实现和基本操作,并附带有带有注释的示例代码。

一、链式队列的定义

链式队列是通过链表实现的一种队列,它将队列的元素通过指针连接起来。链式队列不需要预先分配固定大小的存储空间,因此可以动态增长,更加灵活。

二、链式队列的实现

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

// 定义链式队列
typedef struct {
    Node* front;
    Node* rear;
} LinkedQueue;

三、链式队列的基本操作

①初始化链式队列

// 初始化链式队列
void initLinkedQueue(LinkedQueue* queue) {
    queue->front = NULL;
    queue->rear = NULL;
}

②判断队列是否为空

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

③入队操作

// 入队操作
void enqueue(LinkedQueue* queue, TypeData value) {
    // 创建新节点
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = value;
    newNode->next = NULL;

    if (isEmpty(queue)) {
        // 队列为空,新节点成为队头
        queue->front = newNode;
        queue->rear = newNode;
    } else {
        // 将新节点插入到队尾
        queue->rear->next = newNode;
        queue->rear = newNode;
    }
}

④ 出队操作

// 出队操作
int dequeue(LinkedQueue* queue) {
    int value = -1;
    if (!isEmpty(queue)) {
        // 保存队头节点的值
        value = queue->front->data;

        // 删除队头节点
        Node* temp = queue->front;
        queue->front = queue->front->next;
        free(temp);

        // 队列为空时,更新rear指针
        if (queue->front == NULL) {
            queue->rear = NULL;
        }
    }
    return value;
}

⑤获取队列中元素的个数

// 获取队列的长度
int getQueueLength(LinkedQueue* queue) {
    Node* current = queue->front;
    int length = 0;
    while (current != NULL) {
        length++;
        current = current->next;
    }
    return length;
}

⑥打印队列内元素

// 打印队列内的元素
void printQueue(LinkedQueue* queue) {
    Node* current = queue->front;
    printf("Queue: ");
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}

四、链式队列的应用

链式队列适用于在不确定队列大小的情况下,动态地存储数据。它可以用于解决生产者-消费者问题,以及在需要异步处理数据的情况下。

五、总结

①入队操作:

  • 当队列为空时,新节点既是队头也是队尾。
  • 当队列不为空时,将新节点插入到队尾,并更新rear指针为新节点。
  • 入队操作涉及动态内存分配,要注意释放节点内存以避免内存泄漏。

②出队操作:

  • 在出队操作之前,要先检查队列是否为空,避免出现空队列的错误。
  • 出队操作要删除队头节点,并更新front指针为下一个节点。
  • 如果队列为空,同时要更新rear指针为空。

③判断队列是否为空:

  • 需要根据front指针是否为空来判断队列是否为空。

④获取队列长度:

  • 需要遍历队列中的节点,并计算节点个数来获取队列长度。

⑤动态内存管理:

  • 在链式队列中,需要使用malloc函数为节点分配内存空间。
  • 在节点不再需要时,要使用free函数释放节点的内存空间,以避免内存泄漏。

⑥打印队列元素:

  • 可以通过遍历队列的节点,并输出节点的数据来打印队列中的元素。

⑦队列的初始化:

  • 在使用链式队列之前,要先对其进行初始化,将front和rear指针都设置为空。

⑧注意空队列和满队列:

  • 链式队列一般不会出现满队列的情况,但要注意空队列的处理,以避免出现空指针引用错误。

⑨链表的插入和删除:

  • 在链式队列中,入队操作涉及链表的插入,而出队操作涉及链表的删除。要确保插入和删除的指针操作正确,避免出现内存泄漏或者空指针错误。

⑩异常处理:

  • 在队列操作时,要考虑异常情况,如空队列出队、空指针操作等,要对这些情况进行适当的处理,避免程序崩溃或出现不可预料的错误。

六、全部代码

①listqueue.h

#ifndef _LISTQUEUE_H_
#define _LISTQUEUE_H_
#include <stdio.h>
#include <stdlib.h>
typedef int TypeData;
typedef struct Node {
    TypeData data;
    struct Node* next;
} Node;

typedef struct {
    Node* front;
    Node* rear;
} LinkedQueue;

// 初始化链式队列
void initLinkedQueue(LinkedQueue* queue);

// 判断队列是否为空
int isEmpty(LinkedQueue* queue);

// 入队操作
void enqueue(LinkedQueue* queue, TypeData value) ;

// 出队操作
int dequeue(LinkedQueue* queue);

// 获取队列的长度
int getQueueLength(LinkedQueue* queue)

// 打印队列内的元素
void printQueue(LinkedQueue* queue);

#endif

②listqueue.c

#include "listqueue.h"
// 初始化链式队列
void initLinkedQueue(LinkedQueue* queue) {
    queue->front = NULL;
    queue->rear = NULL;
}

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

// 入队操作
void enqueue(LinkedQueue* queue, TypeData value) {
    // 创建新节点
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = value;
    newNode->next = NULL;

    if (isEmpty(queue)) {
        // 队列为空,新节点成为队头
        queue->front = newNode;
        queue->rear = newNode;
    } else {
        // 将新节点插入到队尾
        queue->rear->next = newNode;
        queue->rear = newNode;
    }
}

// 出队操作
int dequeue(LinkedQueue* queue) {
    int value = -1;
    if (!isEmpty(queue)) {
        // 保存队头节点的值
        value = queue->front->data;

        // 删除队头节点
        Node* temp = queue->front;
        queue->front = queue->front->next;
        free(temp);

        // 队列为空时,更新rear指针
        if (queue->front == NULL) {
            queue->rear = NULL;
        }
    }
    return value;
}

// 获取队列的长度
int getQueueLength(LinkedQueue* queue) {
    Node* current = queue->front;
    int length = 0;
    while (current != NULL) {
        length++;
        current = current->next;
    }
    return length;
}

// 打印队列内的元素
void printQueue(LinkedQueue* queue) {
    Node* current = queue->front;
    printf("Queue: ");
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}

③listqueue_main.c

#include "listqueue.h"
#include "listqueue.c"
int main() {
    LinkedQueue queue;
    initLinkedQueue(&queue);

    // 入队操作
    enqueue(&queue, 10);
    enqueue(&queue, 20);
    enqueue(&queue, 30);

    // 打印队列内的元素
    printQueue(&queue);

    // 获取队列长度
    int length = getQueueLength(&queue);
    printf("Queue length: %d\n", length);

    // 出队操作
    int value = dequeue(&queue);
    printf("Dequeued value: %d\n", value);

    // 打印出队后的队列
    printQueue(&queue);

    // 获取出队后的队列长度
    length = getQueueLength(&queue);
    printf("Queue length: %d\n", length);

    return 0;
}

七、结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/45361.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据分享】1999—2021年地级市地方一般公共预算收支状况(科学技术支出/教育支出等)

在之前的文章中&#xff0c;我们分享过基于2000-2022年《中国城市统计年鉴》整理的1999-2021年地级市的人口相关数据、各类用地面积数据、污染物排放和环境治理相关数据、房地产投资情况和商品房销售面积、社会消费品零售总额和年末金融机构存贷款余额&#xff08;可查看之前的…

STM32CubeIDE(串口)

目录 一、轮询模式 1.1 配置USART2为异步模式 1.2 500ms发送一次消息 1.3 通信结果 1.4 串口控制LED 二、中断收发 2.1 开启中断 2.2 中断发送接收 2.2.1 中断发送只需要调用接口 2.2.2 中断接收 2.3 实验结果 三、DMA模式与收发不定长数据 3.1 DMA通道配置 3.2 DMA…

【MATLAB绘图】

MATLAB绘图函数&#xff1a;Plot函数详解 介绍 MATLAB是一种常用的科学计算和数据可视化工具&#xff0c;它提供了强大的绘图函数&#xff0c;使用户能够创建各种类型的图表和图形。 基本语法 plot函数的基本语法如下&#xff1a; plot(x, y)其中&#xff0c;x和y是长度相…

Vue 本地应用 图片切换 v-show v-bind实践

点击切换图片的本质&#xff0c;其实修改的是img标签的src属性。 图片的地址有很多个&#xff0c;在js当中通过数组来保存多个数据&#xff0c;数组的取值结合索引&#xff0c;根据索引可以来判断是否是第一张还是最后一张。 图片的变化本质是src属性被修改了&#xff0c;属性…

Shell输出帮助手册

代码&#xff1a; 帮助手册雏形 function help(){echo -e "Help manual":echo -e " -h. -- help View the help manual"echo -e " install Installation"echo -e " uninstall Uninstall" }case "$1&qu…

设计模式——单例模式

1 概述 单例模式就是保证一个类只有一个对象实例。 为了保证无法创建多余的对象实例&#xff0c;单例类中需要自己创建对象实例&#xff0c;并把自己的构造方法私有化以防止其他地方调用创建对象&#xff0c;且需要提供一个公共的方法给其他类来获取该单例类的实例。 同时单例…

初识TDMQ

目录 一&#xff1a;需求背景二&#xff1a;相关文档三&#xff1a;验证TDMQ广播消息 一&#xff1a;需求背景 目前公司需要将决策引擎处理的结果&#xff0c; 一部分数据交给下游分析/入黑/通知等功能。因此就需要决策引擎生产结果让多方下游去消费。 而我需要实现下游的一部…

flutter开发实战-jsontodart及 生成Dart Model类

flutter开发实战-jsontodart及 生成Dart Model类。 在开发中&#xff0c;经常遇到请求的数据Json需要转换成model类。这里记录一下Jsontodart生成Dart Model类的方案。 一、JSON生成Dart Model类 在开发中经常用到将json转成map或者list。通过json.decode() 可以方便 JSON 字…

AMEYA360谈:村田新款超声波传感器,能实现15cm近距离检测

随着近年来ADAS的精度越来越高&#xff0c;对用于自动刹车和自动泊车的障碍物检测系统提出了更高的检测性能要求。配备在障碍物检测系统中的超声波传感器需要在短距离和长距离的情况下都具有很高的检测精度&#xff0c;并且谐振频率和静电容量的公差很小&#xff0c;以稳定精度…

AI学习笔记三:编写检测的yolov5测试代码

若该文为原创文章&#xff0c;转载请注明原文出处。 通过detect.py代码测试通过后&#xff0c;阅读detect.py代码发现&#xff0c;有些难以看懂&#xff0c;看得有点蒙蒙的&#xff0c; 所以编写了一个简单的测试程序。 代码如下&#xff1a; import cv2 import numpy as np…

基于AOP实现登录日志和操作日志(新手入门版)

基于AOP实现登录日志和操作日志 目录结构代码PostMan测试代码控制台查看输出解析成JSON如果你觉得对你有帮助的话&#xff0c;请点赞收藏 目录结构 代码 package com.demo.mymaintest.constants;import java.lang.annotation.Documented; import java.lang.annotation.ElementT…

Emvirus: 基于 embedding 的神经网络来预测 human-virus PPIs【Biosafety and Health,2023】

研究背景&#xff1a; Human-virus PPIs 预测对于理解病毒感染机制、病毒防控等十分重要&#xff1b;大部分基于 machine-learning 预测 human-virus PPIs 的方法利用手动方法处理序列特征&#xff0c;包括统计学特征、系统发育图谱、理化性质等&#xff1b;本文作者提出了一个…

全志F1C200S嵌入式驱动开发(spi-nor image制作)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 一般soc系统里面添加spi-nor flash芯片,特别是对linux soc来说,都是把它当成文件系统来使用的。spi-nor flash和spi-nand flash相比,虽然空间小了点,但是胜在稳定,这是很多工业…

linux编译内核

新安装的ubuntu18&#xff0c;补齐依赖工具包。 sudo apt install vim sudo apt install net-tools sudo apt-get install libncurses5-dev libssl-dev build-essential openssl sudo apt-get install flex sudo apt-get install bison -y sudo apt-get install openssh-s…

数据结构【栈和队列】

第三章 栈与队列 一、栈 1.定义&#xff1a;只允许一端进行插入和删除的线性表&#xff0c;结构与手枪的弹夹差不多&#xff0c;可以作为实现递归函数&#xff08;调用和返回都是后进先出&#xff09;调用的一种数据结构&#xff1b; 栈顶&#xff1a;允许插入删除的那端&…

logback-spring.xml日志配置文件详解

目录 前言logback-spring.xml 配置 前言 打印日志是一个系统的基本功能&#xff0c;系统出现异常可以通过查找日志弄清楚是什么原因&#xff0c;从而更加快速地定位问题&#xff0c;修复系统。 logback-spring.xml 配置 文件位置 具体配置 <?xml version"1.0"…

代理模式(java)

目录 结构 静态代理案例 代码实现 售票类 火车站类 代理类 测试类 优缺点 优点 缺点 结构 代理&#xff08;Proxy&#xff09;模式分为三种角色&#xff1a; 抽象主题&#xff08;Subject&#xff09;类&#xff1a; 通过接口或抽象类声明真实主题和代理对象实现的业务…

Windows Server 2022 中文版、英文版下载 (updated Jul 2023)

Windows Server 2022 中文版、英文版下载 (updated Jul 2023) Windows Server 2022 正式版&#xff0c;2023 年 7 月更新 请访问原文链接&#xff1a;https://sysin.org/blog/windows-server-2022/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&a…

【HTML5】拖放详解及实现案例

文章目录 效果预览代码实现 效果预览 代码实现 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>一颗不甘坠落的流星</title><style>#div1,#div2 {float: left;width: 100px;height: 27px;margin: 10px;paddin…

性能测试Ⅱ(压力测试与负载测试详解)

协议 性能理论&#xff1a;并发编程 &#xff0c;系统调度&#xff0c;调度算法 监控 压力测试与负载测试的区别是什么&#xff1f; 负载测试 在被测系统上持续不断的增加压力&#xff0c;直到性能指标(响应时间等)超过预定指标或者某种资源(CPU&内存)使用已达到饱和状…