数据结构-3.6.队列的链式实现

news2024/11/18 19:42:56

队列可以理解为单链表的阉割版,相比单链表而言,队列只有在添加和删除元素上和单链表有区别


一.队列的链式实现:

1.图解:

2.代码:

#include<stdio.h>
​
typedef struct LinkNode //链式队列结点 
{
    int data;
    struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{
    LinkNode *front; //队头指针
    LinkNode *rear; //队尾指针 
}LinkQueue;
​
int main()
{
    return 0;
}

二.初始化队列:

1.带头结点:

a.图解:

b.代码:
#include<stdio.h>
#include<stdlib.h>
​
typedef struct LinkNode //链式队列结点 
{
    int data;
    struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{
    LinkNode *front; //队头指针
    LinkNode *rear; //队尾指针 
}LinkQueue;
​
//初始化队列(带头结点)
void InitQueue(LinkQueue &Q)
{
    //初始化时,front和rear都指向头结点
    Q.front = Q.rear = (LinkNode *)malloc(sizeof(LinkNode));//malloc用于申请一个头结点 
    Q.front -> next=NULL; //头指针下一个元素为NULL,因为一开始什么都没有 
} 
​
//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{
    if( Q.front==Q.rear ) //也可以这么判断:如果Q.front -> next==NULL,此时队列为空 
    {
        return true; //代表队列为空 
    }
    else
    {
        return false; //代表队列不为空 
    }
} 
​
int main()
{
    LinkQueue Q;//声明一个队列
    InitQueue(Q); //初始化队列
    //后续操作。。。 
    return 0;
}

2.不带头结点:

a.图解:

b.代码:
#include<stdio.h>
​
typedef struct LinkNode //链式队列结点 
{
    int data;
    struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{
    LinkNode *front; //队头指针
    LinkNode *rear; //队尾指针 
}LinkQueue;
​
//初始化队列(不带头结点)
void InitQueue(LinkQueue &Q)
{
    //初始化时,front和rear都指向NULL
    Q.front=NULL;
    Q.rear=NULL; 
}
​
//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{
    if( Q.front==NULL ) //只需要看头指针是否等于NULL即可,也可以看Q.rear是否为NULL,是的话队列为空 
    {
        return true; //代表队列为空,头指针为NULL,代表没有头指针,自然队列为空 
    }
    else
    {
        return false; //代表队列不为空 
    }
}  
​
int main()
{
    LinkQueue Q;//声明一个队列
    InitQueue(Q); //初始化队列
    //后续操作。。。
    return 0;
}

三.入队操作:

1.带头结点:

a.图解:

b.代码:
#include<stdio.h>
#include<stdlib.h>
​
typedef struct LinkNode //链式队列结点 
{
    int data;
    struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{
    LinkNode *front; //队头指针
    LinkNode *rear; //队尾指针 
}LinkQueue;
​
//初始化队列(带头结点)
void InitQueue(LinkQueue &Q)
{
    //初始化时,front和rear都指向头结点
    Q.front = Q.rear = (LinkNode *)malloc(sizeof(LinkNode));//malloc用于申请一个头结点 
    Q.front -> next=NULL; //头指针下一个元素为NULL,因为一开始什么都没有 
} 
​
//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{
    if( Q.front==Q.rear ) //也可以这么判断:如果Q.front -> next==NULL,此时队列为空 
    {
        return true; //代表队列为空 
    }
    else
    {
        return false; //代表队列不为空 
    }
} 
​
//新元素入队(带头结点)
void EnQueue(LinkQueue &Q,int x)//只是让x入队,不改变x的值,所以无需&
{
    LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode)); //用malloc申请一个新结点用来存要入队的元素 
    s->data = x; //把新插入的元素x放入新结点中 
    s->next = NULL; //由于队列入队的操作是在表尾的位置进行,因此新插入的结点是队列的最后一个结点,后面就是NULL 
    Q.rear->next = s;
    /*由于一开始rear指针指向的是当前的表尾结点,而新插入的新结点应该连到表尾结点之后,
      所以要把rear指向的结点next指针域指向新结点s */
    Q.rear = s; //修改表尾指针指向新添加的元素,新添加的元素就是表尾元素 
} 
​
int main()
{
    LinkQueue Q;//声明一个队列
    InitQueue(Q); //初始化队列
    //后续操作。。。 
    return 0;
}

2.不带头结点:

a.图解:

b.代码:
#include<stdio.h>
#include<stdlib.h> 
​
typedef struct LinkNode //链式队列结点 
{
    int data;
    struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{
    LinkNode *front; //队头指针
    LinkNode *rear; //队尾指针 
}LinkQueue;
​
//初始化队列(不带头结点)
void InitQueue(LinkQueue &Q)
{
    //初始化时,front和rear都指向NULL
    Q.front=NULL;
    Q.rear=NULL; 
}
​
//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{
    if( Q.front==NULL ) //只需要看头指针是否等于NULL即可,也可以看Q.rear是否为NULL,是的话队列为空 
    {
        return true; //代表队列为空,头指针为NULL,代表没有头指针,自然队列为空 
    }
    else
    {
        return false; //代表队列不为空 
    }
}  
​
//新元素入队(不带头结点)
void EnQueue(LinkQueue &Q,int x)
{
    LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));//用malloc申请一个新结点用来存要入队的元素 
    s->data = x;//把新插入的元素x放入新结点中
    s->next = NULL;//由于队列入队的操作是在表尾的位置进行,因此新插入的结点是队列的最后一个结点,后面就是NULL 
    if( Q.front==NULL ) //在空队列中插入第一个元素,插入第一个元素时Q.front为NULL,因为刚开始front和rear都指向NULL 
    { //如果队列为空,那么插入的元素就是队列第一个元素 
        //修改队头和队尾指针 
        Q.front = s;
        Q.rear = s;
    }
    else
    {
        Q.rear->next = s;//新结点插入到rear结点之后 
        Q.rear = s;//修改rear指针 
    }
} 
​
int main()
{
    LinkQueue Q;//声明一个队列
    InitQueue(Q); //初始化队列
    //后续操作。。。
    return 0;
}

四.出队操作:

1.带头结点:

a.图解:

不是最后一个元素出队:

最后一个元素出队:

b.代码:
#include<stdio.h>
#include<stdlib.h>
​
typedef struct LinkNode //链式队列结点 
{
    int data;
    struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{
    LinkNode *front; //队头指针
    LinkNode *rear; //队尾指针 
}LinkQueue;
​
//初始化队列(带头结点)
void InitQueue(LinkQueue &Q)
{
    //初始化时,front和rear都指向头结点
    Q.front = Q.rear = (LinkNode *)malloc(sizeof(LinkNode));//malloc用于申请一个头结点 
    Q.front -> next=NULL; //头指针下一个元素为NULL,因为一开始什么都没有 
} 
​
//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{
    if( Q.front==Q.rear ) //也可以这么判断:如果Q.front -> next==NULL,此时队列为空 
    {
        return true; //代表队列为空 
    }
    else
    {
        return false; //代表队列不为空 
    }
} 
​
//队头元素出队(带头结点)
bool DeQueue(LinkQueue &Q,int &x) //最终x会变为要删除的元素,所以需要& 
{
    if( Q.front==Q.rear )
    {
        return false;//空队,就无法出队即删除元素 
    }
    //此时队列不为空
    //Q.front为头结点 
    LinkNode *p = Q.front->next; //让p指针指向要删除的结点,对于带头结点的队列来说就是要删除头结点的后一个结点 
    x = p->data; //用变量x返回队头元素即要删除的元素 
    Q.front->next = p->next; //修改头结点的next指针
    if( Q.rear==p ) //此次是最后一个结点出队,最终就是空队列即Q.rear=Q.front 
    {
        Q.rear=Q.front; //修改rear指针 
    } 
    free(p); //释放结点空间
    return true; 
} 
​
int main()
{
    LinkQueue Q;//声明一个队列
    InitQueue(Q); //初始化队列
    //后续操作。。。 
    return 0;
}

2.不带头结点:

a.图解:

b.代码:
#include<stdio.h>
#include<stdlib.h>
​
typedef struct LinkNode //链式队列结点 
{
    int data;
    struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{
    LinkNode *front; //队头指针
    LinkNode *rear; //队尾指针 
}LinkQueue;
​
//初始化队列(不带头结点)
void InitQueue(LinkQueue &Q)
{
    //初始化时,front和rear都指向NULL
    Q.front=NULL;
    Q.rear=NULL; 
}
​
//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{
    if( Q.front==NULL ) //只需要看头指针是否等于NULL即可,也可以看Q.rear是否为NULL,是的话队列为空 
    {
        return true; //代表队列为空,头指针为NULL,代表没有头指针,自然队列为空 
    }
    else
    {
        return false; //代表队列不为空 
    }
}  
​
//队头元素出队(不带头结点)
bool DeQueue(LinkQueue &Q,int &x)
{
    if( Q.front==NULL )
    {
        return false; //空队 
    }
    LinkNode *p=Q.front; //p指向此次出队的结点即front指针指向的结点出队 
    x = p->data; //用变量x返回队头元素 
    Q.front = p->next; //由于没有头结点,所以每次有队头元素出队后都需要修改front指针的指向 
    if( Q.rear==p ) //此次是最后一个结点出队,最终就是空队列 
    {
        Q.front=NULL; //front指向NULL 
        Q.rear=NULL; //rear指向NULL  
    } 
    free(p); //释放结点空间 
    return true; 
} 
​
int main()
{
    LinkQueue Q;//声明一个队列
    InitQueue(Q); //初始化队列
    //后续操作。。。
    return 0;
}

五.队列满的条件:


六.统计队列的长度:

思路:

从队头结点开始依次往后遍历,统计总共有多少个结点,显然时间复杂度为O(n)。


七.总结:


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

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

相关文章

【韩顺平Java笔记】第1章

0-1可以看视频&#xff0c;下面记录主要内容 2. 就业方向 Java基础又叫JavaSE&#xff0c;Java有三个主要的就业方向&#xff1a; JavaEE软件工程师&#xff1a;电商&#xff0c;团购&#xff0c;众筹&#xff0c;sns&#xff08;社交网络&#xff09;&#xff0c;教育&…

纠删码参数自适应匹配问题ECP-AMP实验方案(一)

摘要 关键词&#xff1a;动态参数&#xff1b;多属性决策&#xff1b;critic权重法&#xff1b;DBSCA聚类分析 引言 云服务存储系统是一种基于互联网的数据存储服务&#xff0c;它可以为用户提供大规模、低成本、高可靠的数据存储空间。云服务存储系统的核心技术之一是数据容…

winsoft公司Utils组件功能简介

Winsoft Utils Library 2.3 是一个为 Delphi 和 C Builder&#xff08;版本 7 到 12 Athens&#xff09;设计的实用工具库。它提供了一系列组件和类&#xff0c;旨在简化和增强开发过程。以下是一些主要功能和特点&#xff1a; 1.组件集合&#xff1a;包含多种实用组件&#x…

AB plc设备数据 转profinet IO项目案例

目录 1 案例说明 1 2 VFBOX网关工作原理 1 3 准备工作 2 4 网关采集AB PLC数据 2 5 用PROFINET IO协议转发数据 4 6 案例总结 7 1 案例说明 设置网关采集AB PLC数据把采集的数据转成profinet IO协议转发给其他系统。 2 VFBOX网关工作原理 VFBOX网关是协议转换网关&#xff0…

如果再回到从前——备忘录模式

文章目录 如果再回到从前——备忘录模式如果再给我一次机会……游戏存进度备忘录模式备忘录模式基本代码游戏进度备忘 如果再回到从前——备忘录模式 如果再给我一次机会…… 时间&#xff1a;5月6日18点  地点&#xff1a;小菜、大鸟住所的客厅  人物&#xff1a;小菜、…

Sharding-JDBC笔记03-分库分表代码示例

文章目录 一、水平分库1. 将原有order_db库拆分为order_db_1、order_db_22. 分片规则修改分片策略standardcomplexinlinehintnone 3. 插入测试4. 查询测试5. 使用分库分片键查询测试总结 二、公共表1. 创建数据库2. 在Sharding-JDBC规则中修改3. 数据操作4. 字典操作测试5. 字典…

Linux线程-POSIX信号量与锁以及条件变量

POSIX信号量 POSIX没有元素这个概念相比于SYSTEM-V更简洁&#xff0c;POSIX不一定适用老版本&#xff1b;二者都是系统范畴&#xff0c;都需要手动删除&#xff0c;POSIX相关函数属于线程库&#xff0c;所有编译时需要末尾加上-lpthread选项 POSIX POSIX有名信号量 主要用于进…

华为 HCIP-Datacom H12-821 题库 (29)

&#x1f423;博客最下方微信公众号回复题库,领取题库和教学资源 &#x1f424;诚挚欢迎IT交流有兴趣的公众号回复交流群 &#x1f998;公众号会持续更新网络小知识&#x1f63c; 1.BFD 为确保两端系统都知道状态的变化&#xff0c;在BFD 状态机的建立和拆除时都采用三次握手…

【LeetCode:75. 颜色分类 + 快速排序】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

图像超分辨率(SR)

图像超分辨率&#xff08;Image Super-Resolution, SR&#xff09;是一种图像处理技术&#xff0c;旨在从低分辨率&#xff08;LR&#xff09;图像中恢复出高分辨率&#xff08;HR&#xff09;图像。这种技术通过增加图像中的细节和清晰度来提高图像的视觉质量&#xff0c;从而…

微信支付准备工作之内网穿透2024/9/28

微信支付部分好像做不了&#xff0c;但是跟着写了点东西。 做项目的微信支付功能时&#xff0c;微信后台需要调用到商户管理系统&#xff0c;但是我们的管理系统写在自己的电脑里。微信后台如何调用到商户系统&#xff1f;内网穿透。 还有如何保证调用过程数据安全&#xff1…

PowerDesigner 16.5安装教程 + 轻松解决软件证书过期导致的无法使用问题

目录 背景: 安装教程 &#xff1a; 证书过期的解决方法&#xff1a; 背景: PowerDesigner16.5凭借强大的功能集成、广泛的兼容性和高效的模型驱动开发方法成为了企业级建模于设计领域的佼佼者。无论是在企业信息化建设、软件开发项目还是数据库设计于管理等领域它都能提有利…

【步联科技身份证】 身份证读取与解析———未来之窗行业应用跨平台架构

一、身份证解析代码 C# function 身份证数据解析_湖南步联科技(wzxx) {var result {};result[xm] wzxx.substr(0, 15);result[xbdm] wzxx.substr(15, 1);result[mzdm] wzxx.substr(16, 2);result[csrq] wzxx.substr(18, 8);result[dzmc] wzxx.substr(26, 35);result[gms…

论文阅读 | HiDDeN网络架构

ECCV 2018 斯坦福-李飞飞团队 一、问题描述 受以下启发&#xff1a; 对抗性例子的发现&#xff1a;深度学习模型在图像识别任务中对微小的、难以察觉的输入扰动非常敏感&#xff0c;这些扰动可以导致模型错误分类图像。这一现象表明&#xff0c;神经网络可以在图像中编码信息&…

一文上手SpringSecurity【五】

对于前后端不分离的项目,我们可以采用一文上手SpringSecurity【四】当中的方式来自定义用户的登录页面和数据源,数据源目前采用的是模拟的方式来实现的,本篇内容主要介绍一下spring security对于前后端分离项目如何实现认证和授权的. 一、前后端分离的认证面对的问题 1.1 传统…

File systems

inode descriptor 文件系统中核心的数据结构就是inode和file descriptor。后者主要与用户进程进行交互。 inode&#xff0c;这是代表一个文件的对象&#xff0c;并且它不依赖于文件名。实际上&#xff0c;inode是通过自身的编号来进行区分的&#xff0c;这里的编号就是个整数…

修改 idea 的 Terminal 命令窗口使用 git-bash

修改配置方法 实际使用效果 &#xff08;END&#xff09;

Java Stream 神技!10招顶级技巧,让你的代码简洁又高效!

哈喽&#xff0c;欢迎来到【程序视点】&#xff0c;我是小二哥。 引言 你是否曾在编写Java代码时&#xff0c;为了处理集合而感到头痛不已&#xff1f;是否在寻找一种更优雅、更简洁的方式来简化你的代码&#xff1f; 如果你的答案是肯定的&#xff0c;那么Java Stream API无…

org.eclipse.paho.client.mqttv3.MqttException: 无效客户机标识

需求背景 最近有一个项目,需要用到阿里云物联网,不是MQ。发现使用原来EMQX的代码去连接阿里云MQTT直接报错,试了很多种方案都不行。最终还是把错误分析和教程都整理一下。 需要注意的是,阿里云物联网平台和MQ不一样。方向别走偏了。 概念描述 EMQX和阿里云MQTT有什么区别…

OpenCV视频I/O(6)检查视频捕获对象是否已成功打开的函数isOpened()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 如果视频捕获已经初始化&#xff0c;则返回 true。 如果之前调用 VideoCapture 构造函数或 VideoCapture::open() 成功&#xff0c;则该方法返回…