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

news2025/1/6 19:37:47

数据结构中的链式队列

目录

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

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

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

在数据结构中,队列(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;
}

七、结果

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MySQL】存储引擎(六)

&#x1f697;MySQL学习第六站~ &#x1f6a9;本文已收录至专栏&#xff1a;MySQL通关路 ❤️文末附全文思维导图&#xff0c;感谢各位点赞收藏支持~ 一.引入 大家可能没有听说过存储引擎&#xff0c;但是一定听过引擎这个词&#xff0c;引擎就是发动机&#xff0c;是一个机器…

PCB封装设计指导(十五)验证封装的正确性

PCB封装设计指导(十五)验证封装的正确性 封装建立好之后,我们需要验证封装是否能够正常的放入PCB文件中,最好最直接的办法就是直接放入PCB中来验证。 具体操作如下 任意新建一个空白的PCB文件点击File 选择NEW

搭建关键字驱动自动化测试框架

前言 上篇文章我们已经了解到了数据驱动自动化测试框架是如何构建和驱动测试的&#xff01;那么这篇文章我们将了解关键字驱动测试又是如何驱动自动化测试完成整个测试过程的。关键字驱动框架是一种功能自动化测试框架&#xff0c;它也被称为表格驱动测试或者基于动作字的测试…

一站式解决方案:Qt 跨平台开发灵活可靠

Qt 是一种跨平台开发工具&#xff0c;为开发者提供了一站式解决方案。无论您的项目目标是 Windows、Linux、macOS、嵌入式系统还是移动平台&#xff0c;Qt 都能胜任。这种跨平台的特性不仅节省开支&#xff0c;还推动了战略的快速落地。 适用范围广泛&#xff1a;Qt 可在多种操…

从新手到专业人士:探索 C++ STL 以获得终极性能

探索 C STL 以获得终极性能 博主简介一、引言二、C STL 简介2.1、STL 是什么&#xff1f;2.2、STL 中的常用组件2.3、STL 的优点 三、入门指南&#xff1a;了解基本概念和用法3.1、容器&#xff1a;vector、list、deque、set、map 等3.2、算法&#xff1a;查找、排序、遍历等3.…

C# IO FileStream流(一)使用整理

一、C# IO 文件流&#xff0c;常用操作整理 来自其他开发者的整理&#xff1a; 文件操作常用相关类 1)Directory //操作目录&#xff08;文件夹&#xff09;&#xff0c;静态类。2)Path//静态类&#xff0c;对文件或目录的路径进行操作&#xff08;很方便&#xff09;【字符…

解决Element-Plus中Swtich @change自动被触发的问题

如图所示 这个switchChange事件在初始化的时候会被自动触发 烦得很 解决方法 如图所示 第471行 通过判断是否还有其它某元素再往下执行 如果你有其它方法 请你在评论区教我下哈 3q

智慧园区楼宇合集 | 图扑数字孪生管控系统

智慧园区是指将物联网、大数据、人工智能等技术应用于传统建筑和基础设施&#xff0c;以实现对园区的全面监控、管理和服务的一种建筑形态。通过将园区内设备、设施和系统联网&#xff0c;实现数据的传输、共享和响应&#xff0c;提高园区的管理效率和运营效益&#xff0c;为居…

【MySQL】索引 (八)

&#x1f697;MySQL学习第八站~ &#x1f6a9;本文已收录至专栏&#xff1a;MySQL通关路 ❤️文末附全文思维导图&#xff0c;感谢各位点赞收藏支持~ 一.引入 索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构(有序)。数据库除了存储数据之外&#xff0c;…

Vue异步更新、$nextTick

需求&#xff1a;编辑标题, 编辑框自动聚焦 1. 点击编辑&#xff0c;显示编辑框 2. 让编辑框&#xff0c; 立刻获取焦点 this. isShowEdit true // 显示输入框 this . $refs . inp . focus () // 获取焦点 问题&#xff1a;"显示之后"&#xff0c;立刻获…

Bash编程

目录&#xff1a; bash编程语法bash脚本编写 1.bash编程语法 Bash 编程基础 变量引号数组控制语句函数 Bash 变量 语法&#xff1a; Variable_namevalue Bash 变量定义的规则 变量名区分大小写&#xff0c;a和A为两个不同的变量。变量名可以使用大小写字母混编的形式进行…

淘票猫影城系统-Spring Boot版

文章目录 一、引言TIPSticketcatticketcat-wechat-miniprogramticketcat-web-userticketcat-web-manager 三、项目截图wechat-miniprogramweb-userweb-manager 四、License 前往闪闪の小窝以获得更好的阅读和评论体验 一、引言 项目地址&#xff1a; 项目名项目内容项目地址开…

【Java】String类常用方法总结

文章目录 1丶boolean equals(Object anObject) 方法2丶int compareTo(String s) 方法3、 int compareToIgnoreCase(String str) 方法4丶字符串查找常用方法.5.丶字符串转化常用方法.大小写转换字符串转数组 6丶字符串替换7丶字符串拆分8丶字符串截取9丶去掉左右空格&#xff08…

备战秋招 | 笔试强训14

目录 一、选择题 二、编程题 三、选择题题解 四、编程题题解 一、选择题 1、下列有关this指针使用方法的叙述正确的是&#xff08;&#xff09; A. 保证基类保护成员在子类中可以被访问 B. 保证基类私有成员在子类中可以被访问 C. 保证基类共有成员在子类中可以被访问 D.…

机器学习 day31(baseline)

语音识别的Jtrain、Jcv和人工误差 对于逻辑回归问题&#xff0c;Jtrain和Jcv可以用分类错误的比例&#xff0c;这一方式来代替单单只看Jtrain&#xff0c;不好区分是否高偏差。可以再计算人类识别误差&#xff0c;即人工误差&#xff0c;作为基准线Jtrain与baseline对比只高了…

keepalived + lvs (服务端socket 客户端socket) udp协议

1、Keepalived 1. 1 keepalived 简介 1.1.1 什么是keepalived Keepalived一个基于VRRP 协议来实现的 LVS 服务高可用方案&#xff0c;可以利用其来解决单点故障。一个LVS服务会有2台服务器运行Keepalived&#xff0c;一台为主服务器&#xff08;MASTER&#xff09;&#xff…

MFC第二十二天 三种绘图句柄与三大坐标系(三大CDC派生类)简介以及应用、Invalidate刷新函数的功能和用法简介

文章目录 三种绘图句柄与三大坐标系&#xff08;三大CDC派生类&#xff09;简介以及应用三种HDC句柄三大CDC派生类什么是放泄露架构使用HDC句柄进行常见图形绘制演示 HPEN和HBRUSH句柄HPEN的创建 Invalidate刷新函数的功能和用法简介应用Win32下MFC下 附录 三种绘图句柄与三大坐…

【算法题解】51. 二叉树的最近公共祖先

这是一道 中等难度 的题 https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/ 题目 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为…

Transformer+医学图像最新进展【2023】

Transformer主要用于自然语言处理领域。近年来,它在计算机视觉(CV)领域得到了广泛的应用。医学图像分析(MIA,Medical image analysis)作为机器视觉(CV,Computer Vision)的一个重要分支,也极大地受益于这一最先进的技术。 机构:新加坡国立大学机械工程系、中山大学智能系…

MySQL创建全文索引时,遇到“Temporary file write failure”的错误

MySQL创建全文索引时&#xff0c;遇到“Temporary file write failure”的错误 环境信息 MySQL Version: 8.0.28 engine: InnoDB rows: 100 index length: 10MB data length: 30MB 笔者在MYSQL上执行创建添加全文索引的语句&#xff1a;alter table users add fulltext index …