数据结构 - 队列

news2024/9/19 10:24:05

一.队列的定义

1.队列的分类

        队列根据存储结构可以分为 顺序队列链式队列

2.队列的结构

①.顺序队列

        顺序队列的 front 指向队首元素的前一个下标

②.链式队列

二.顺序队列的基本运算

0.顺序队列的结构体定义

typedef int data_t;

typedef struct 
{
    data_t *data;                     //用数组作为队列的存储空间
    int front,rear;                 // front 为队头前一个位置的下标 , rear 为队列尾部的下标
}sequeue_t;

1.创建一个空队列

/**
 * @description:            创建一个空队列
 * @param -         :       无
 * @return          :       创建的队列的指针
*/
sequeue_t *Sequeue_Create(void)
{
    sequeue_t *q;

    /* 1.为队列分配空间 */
    q = (sequeue_t *)malloc(sizeof(sequeue_t));
    if(NULL == q)
    {
        printf("malloc error!\n");
        return NULL;
    }

    /* 2.初始化 front 和 rear 都为 MAXSIZE - 1 */
    q->front = q->rear = MAXSIZE - 1;

    return q;
}

2.判断队列是否为满

/**
 * @description:            判断队列是否为满
 * @param - q       :       要操作的队列的指针
 * @return          :       1为满,0为非满
*/
int Sequeue_Is_Full(sequeue_t *q)
{
    if((q->rear + 1) % MAXSIZE == q->front)
        return 1;
    else
        return 0;
}

3.判断队列是否为空

/**
 * @description:            判断队列是否为空
 * @param - q       :       要操作的队列的指针
 * @return          :       1为空,其他为非空
*/
int Sequeue_Is_Empty(sequeue_t *q)
{
    if(q->rear == q->front)
        return 1;
    else
        return 0;
}

4.入队

/**
 * @description:                入队
 * @param - q       :           指向队列的指针
 * @param - value   :           入队元素的值
 * @return          :           0为成功,其他为失败
*/
int Sequeue_In(sequeue_t *q,data_t value)
{
    /* 1.先看队列是否已满 */
    if(Sequeue_Is_Full(q))
    {
        printf("queue is already full!\n");
        return -1;
    }

    /* 2.入队,rear 向后移动,(q->rear+1)%MAXSIZE 是为了保证数组不越界,使该队列成为循环队列 */
    q->rear = (q->rear + 1) % MAXSIZE;

    /* 3.写入数据 */
    q->data[q->rear] = value;

    return 0;
}

5.出队

/**
 * @description:            出队
 * @param - q       :       要操作的队列的指针
 * @param - data    :       用于存储出队的元素的值
 * @return          :       0为成功,其他为失败
*/
int Sequeue_Out(sequeue_t *q,data_t *data)
{
    /* 1.判断队列是否为空 */
    if(Sequeue_Is_Empty(q))
    {
        printf("sequeue is already empty!\n");
        return -1;
    }

    /* 2.出队 */
    q->rear = (q->rear + 1) % MAXSIZE;
    *data = q->data[q->front];

    return 0;
}

6.打印队列中元素的值

/**
 * @description:            打印出队列所有元素的值
 * @param - q       :       要操作的队列的指针
*/
void Show_Sequeue(sequeue_t *q)
{
    int i = 0;

    /* 1.若为空,则退出 */
    if(Sequeue_Is_Empty(q))
        return ;

    /* 2.遍历打印队列中的元素 */
    for(i = (q->front+1)%MAXSIZE ; i != (q->rear+1)%MAXSIZE ; i = (i+1)%MAXSIZE)
    {
        printf("%d\t",q->data[i]);
    }
    
    printf("\n");
}

三.链式队列的基本运算

0.链式队列的结构体定义

typedef int data_t;


/* 1.链表结点 */
typedef struct node
{
    data_t data;                    //结点的数据域
    struct node *next;              //指向下一个结点的指针

}link_node;

/* 2.队列的队头和队尾指针 */
typedef struct
{
    link_node *front,*rear;             //front 指向队头元素的前一个结点(即链表的首结点) , rear 指向队尾结点

} linkqueue_t;

1.创建一个空的队列

/**
 * @description:                创建一个空队列
 * @param           :           无
 * @return          :           队列的首结点指针
*/
linkqueue_t *Linkqueue_Create(void)
{
    linkqueue_t *q;

    /* 1.申请队列 front 和 rear 的空间 */
    q = (linkqueue_t *)malloc(sizeof(linkqueue_t));
    if(NULL == q)
    {
        printf("malloc error!\n");
        return NULL;
    }


    /* 2.申请链表中头结点的空间 */
    q->front = (link_node *)malloc(sizeof(link_node));
    if(NULL == q->front)
    {
        printf("malloc error!\n");
        return NULL;
    }
    
    q->front->next = NULL;              //初始化链表首结点的 next = NULL
    q->rear = q->front;                 //初始化 front 和 rear 都指向链表首结点

    return q;
}

2.判断队列是否为空

/**
 * @description:            判断队列是否为空
 * @param - q       :       要操作的队列的指针
 * @return          :       1为空 , 0为非空
*/
int Linkqueue_is_empty(linkqueue_t *q)
{
    return (q->front == q->rear ? 1 : 0);
}

3.入队

/**
 * @description:            入队
 * @param - q       :       要操作的队列的指针
 * @param - value   :       要入队的元素的值
 * @return          :       0为成功,其他为失败
*/
int Linkqueue_In(linkqueue_t *q,data_t value)
{
    link_node *p;               //指向新创建的结点

    /* 1.创建新的结点 */
    p = (link_node *)malloc(sizeof(link_node));
    if(NULL == p)
    {
        printf("malloc error!\n");
        return -1;
    }
        
    /* 2.初始化新结点 */
    p->data = value;
    p->next = NULL;

    /* 3.向链表进行尾插以实现入队 */
    q->rear->next = p;
    q->rear = p;

    return 0;

}   

4.出队

/**
 * @description:            出队 , 使用前需判断队列是否为空
 * @param - q       :       要操作的队列的指针
 * @param - value   :       保存出队的元素的值
 * @return          :       无
*/
void Linkqueue_Out(linkqueue_t *q,data_t *value)
{
    link_node *p;           //用来指向队头元素的前一个结点

    /* 1. p 指向队头的前一个结点( front 就指向了队头元素的前一个结点 ) */
    p = q->front;

    /* 2. front 向后移动 */
    q->front = q->front->next;

    /* 3.保存要出队的值 */
    *value = q->front->data;

    /* 4.释放 p */
    free(p);

}

5.打印队列中的结点

/**
 * @description:            打印队列中的数据
 * @param - q       :       要操作的队列的指针
 * @return          :       无
*/
void Linkqueue_Show(linkqueue_t *q)
{
    link_node  *p;      //用于指向当前链表的结点

    /* 从队头开始遍历打印 */
    for(p = q->front->next ; p != NULL ; p = p->next)
    {
        printf("%d ",p->data);
    }
    printf("\n");
}

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

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

相关文章

stable diffusion 反推提示词插件 tagger 的安装,很详细

stable diffusion 反推提示词插件 tagger 的安装,很详细 一、前言二、下载1、方式一2、方式二 一、前言 最近想下载 stable diffusion 反推提示词插件 tagger ,也是好一番折腾,这里做个记录。 在安装之前确保能正常访问 github &#xff0c…

图像增强技术分析

图像增强是一种图像处理技术,旨在改善图像的视觉质量,使其更适合显示或进一步分析。这种技术可以应用于多种场景,包括医学成像、卫星图像、视频处理以及文本到图像生成模型等领域。图像增强的目标通常是提高图像的某些视觉特征,如…

[内网渗透]---msf基础-永恒之蓝-ms17-010

what Metasploit(通常简称为MSF)是一个开源的渗透测试框架,包含大量的已知漏洞利用模块,可以用来攻击目标系统并获取控制权。 how 实验环境:Kali、带有永恒之蓝漏洞的虚拟机且开启445端口(两个虚拟机同一子网) 1.信…

FPGA-Vivado-IP核-虚拟输入输出(VIO)

VIO IP核 背景介绍 Vivado中的VIO(Virtual Input/Output,虚拟输入/输出) IP核是一种用于调试和测试FPGA设计的IP核。当设计者通过JTAG接口与FPGA芯片连接时,在Vivado的Verilog代码中添加VIO IP核,就可以让设计者与FPG…

TCP 拥塞控制:一场网络数据的交通故事

从前有条“高速公路”,我们叫它互联网,而这条公路上的车辆,则是数据包。你可以把 TCP(传输控制协议)想象成一位交通警察,负责管理这些车辆的行驶速度,以防止交通堵塞——也就是网络拥塞。 第一…

08_Python数据类型_字典

Python的基础数据类型 数值类型:整数、浮点数、复数、布尔字符串容器类型:列表、元祖、字典、集合 字典 字典(Dictionary)是一种可变容器模型,它可以存储任意类型对象,其中每个对象都存储为一个键值对。…

3.4.3 __ipipe_init_early之初始化root domain

点击查看系列文章 》 Interrupt Pipeline系列文章大纲-CSDN博客 3.4.3 __ipipe_init_early之初始化root domain 如下图所示,红框里面的函数当前都是空的,本章还是分析蓝框中的代码片段。 第295行,变量ipd指向了ipipe_root即ipd代表root doma…

Java 入门指南:JVM(Java虚拟机)垃圾回收机制 —— 内存分配和回收规则

文章目录 垃圾回收机制堆空间的基本结构内存分配和回收规则对象优先在 Eden 区分配分配担保机制 大对象直接进入老年代长期存活的对象进入老年代主要进行 GC 的区域部分收集 (Partial GC):Minor GCMajor/Old GCMixed GC 整堆收集(Full GC) 空…

K-means 算法的介绍与应用

目录 引言 K-means 算法的基本原理 表格总结:K-means 算法的主要步骤 K-means 算法的 MATLAB 实现 优化方法与改进 K-means 算法的应用领域 表格总结:K-means 算法的主要应用领域 结论 引言 K-means 算法是一种经典的基于距离的聚类算法&#xff…

中秋献礼!2024年中科院一区极光优化算法+分解对比!VMD-PLO-Transformer-LSTM多变量时间序列光伏功率预测

中秋献礼!2024年中科院一区极光优化算法分解对比!VMD-PLO-Transformer-LSTM多变量时间序列光伏功率预测 目录 中秋献礼!2024年中科院一区极光优化算法分解对比!VMD-PLO-Transformer-LSTM多变量时间序列光伏功率预测效果一览基本介…

人工智能和大模型的简介

文章目录 前言一、大模型简介二、大模型主要功能1、自然语言理解和生成2、文本总结和翻译3、文本分类和信息检索4、多模态处理三、大模型的技术特性1、深度学习架构2、大规模预训练3、自适应能力前言 随着技术的进步,人工智能(Artificial Intelligence, AI)和机器学习(Mac…

TryHackMe 第1天 | Introduction to Cyber Security

偶然之间了解到了TryHackMe这个网站,尝试跟着其中的学习路径进行学习,发现还是挺适合入门网络安全这一领域的。但是这个网站包含了很多内容,如果不用一些东西记录下来,那么很容易忘记,所以打算在此记录一下学习过程。 …

Linux——应用层自定义协议与序列化

目录 一应用层 1再谈 "协议" 2序列化与反序列化 3理解read,write,recv,send 4Udp vs Tcp 二网络版本计算器 三手写序列和反序列化 四进程间关系与守护进程 1进程组 1.1什么是进程组 1.2组长进程 2会话 2.1什么是会话 2.2会话下的前后台进程 3作业控…

nginx实现权重机制(nginx基础配置二)

在上一篇文章中我们已经完成了对轮询机制的测试,详情请看轮询机制。 接下来我们进行权重机制的测试 一、conf配置 upstream backServer{ server 127.0.0.1:8080 weight2; server 127.0.0.1:8081 weight1; } server { listen 80; server_name upstream.boyatop.cn…

一个有趣的“苦无”测试探针笔的设计

设计思路来源 动漫火影中的苦无,在测试过程中多种测试点方便测试,不想每次去找合适的测试工具,例如点测试和连接线测试需要用到不同的接触工具。 PCB设计 这这些焊点都是短接的(除了中间的固定孔),直接使…

Leetcode 验证回文串

使用双指针技术,逐步比较字符串中的字符,并忽略非字母数字字符以及大小写,判断该字符串是否为回文。以下是详细解释: 1. 核心思想: 回文串是指正读和反读都相同的字符串。我们需要从字符串的两端开始比较字符&#x…

Python画笔案例-051 绘制赵爽弦图

1、绘制赵爽弦图 通过 python 的turtle 库绘制 赵爽弦图,如下图: 2、实现代码 绘制 赵爽弦图,以下为实现代码: """赵爽弦图.py本程序演录了如何自定义形状,如何把它添加到造型字典。赵爽弦图是用来证明…

JAVA算法数据结构第一节稀疏矩阵

一、稀疏矩阵介绍: 稀疏矩阵是一种特殊类型的矩阵,其中大部分元素都是零。在处理这类矩阵时,如果仍然使用标准的矩阵存储方式(即传统的二维数组),则会浪费大量的存储空间来保存零值。为了提高存储效率以及…

9.12 TFTP通信

客户端设计(仅供参考): 下载本质:读取服务器发送的数据包,写入到本地文件 上传本质:读取本地文件内容,发送给服务器。 1、建立菜单选项,上传和下载。 2、上传功能函数: …

实用类工具!分享6款AI论文一键生成器免费8000字

在当前的学术研究和写作领域,AI论文生成工具的出现极大地提高了写作效率和质量。这些工具不仅能够帮助研究人员快速生成论文草稿,还能进行内容优化、查重和排版等操作。千笔-AIPassPaper是一款备受推荐的AI论文一键生成器。 千笔-AIPassPaper是一个一站式…