学习记录——day17 数据结构 队列 链式队列

news2024/11/25 16:38:35

队列介绍

1、队列也是操作受限的线性表:所有操作只能在端点处进行,其删除和插入必须在不同端进行

2、允许插入操作的一端称为队尾,允许删除操作的一端称为队头

3、特点:先进先出(FIFO)

4、分类:

        顺序存储的栈称为顺序栈

        链式存储的队列,称为链式队列

顺序队列

1、使用一片连续存储的空间存储队列,并且给定两个变量,分别记录队头和队尾下标

2、普通顺序队列使用中,存在“假溢满”现象

        假溢满:队列中明明还有存储空间,但是由于队尾已经达到了数组的最大下标,不能在继续                          入队元素了

3、为了解决“假溢满”现象,我们引入了循环顺序队列

循环顺序队列

循环顺序队列:通过相关操作,当对头或队尾达到数组最大下标时,可以返回到下标为0的位置

注:以下均使用人为浪费一个空间的方法判满

1、创建

头节点类型定义

//类型重定义
typedef int datatype;


//队列类型结构体
typedef struct Queue
{
    datatype data[MAX];
    int head;
    int tail;

}SeqQueue, *SeqQueuePtr;

创建队列

SeqQueuePtr queue_create()
{
    SeqQueuePtr Q = (SeqQueuePtr)malloc(sizeof(SeqQueue));
    if(NULL == Q)
    {
        return NULL;
    }

    bzero(Q->data,sizeof(Q->data));
    Q->front = Q->tail = 0;

    printf("创建成功 \n");

    return Q;
}

2、判空判满

int queue_empty(SeqQueuePtr Q)
{
    return Q->tail == Q->front;
}

int queue_full(SeqQueuePtr Q)
{
    return (Q->tail+1)%MAX == Q->front;
}

3、插入

void queue_push(SeqQueuePtr Q ,datatype e)
{
    if (NULL == Q || queue_full(Q))
    {
        return;
    }
    
    Q->data[Q->tail] = e;

    Q->tail = (Q->tail+1)%MAX;

    return;
}

4、遍历

void queue_show(SeqQueuePtr Q)
{
    if (NULL == Q)
    {
        return;
    }

    printf("遍历结果:");
    for (int i = Q->front; i !=Q->tail; i=(i+1)%MAX)
    {
        printf("%d\t",Q->data[i]);
    }
    putchar(10);
    return;
}

5、出队

void queue_pop(SeqQueuePtr Q)
{
    if (NULL == Q || queue_empty(Q))
    {
        return;
    }
    
    printf("%d 出队\n",Q->data[Q->front]);

    Q->front = (Q->front+1)%MAX;
}

6、求实际大小

int queue_size(SeqQueuePtr Q)
{
    if (NULL == Q)
    {
        return -1;
    }

    //不使用循环求大小

    int size = ((Q->tail-Q->front)+MAX)%MAX;

    return size;
}

7、销毁

void queue_destroy(SeqQueuePtr Q)
{
    if (NULL != Q)
    {
        free(Q);
        Q = NULL;
    }
    
    printf("boom!!\n");

    return;
}

8、完整代码

dui_lie.h

#ifndef DUI_LEI
#define DUI_LEI

#include <myhead.h>

#define MAX 8
typedef int datatype;

typedef struct 
{
    datatype data[MAX];
    int front;
    int tail;
}SeqQueue,*SeqQueuePtr;

SeqQueuePtr queue_create();

int queue_empty(SeqQueuePtr Q);

int queue_full(SeqQueuePtr Q);

void queue_push(SeqQueuePtr Q ,datatype e);

void queue_show(SeqQueuePtr Q);

void queue_pop(SeqQueuePtr Q);

int queue_size(SeqQueuePtr Q);

void queue_destroy(SeqQueuePtr Q);


#endif // !DUI_LEI.H

dui_lie.c

#include "dui_lie.h"
#include <myhead.h>

SeqQueuePtr queue_create()
{
    SeqQueuePtr Q = (SeqQueuePtr)malloc(sizeof(SeqQueue)*MAX);
    if(NULL == Q)
    {
        return NULL;
    }

    bzero(Q->data,sizeof(Q->data));
    Q->front = Q->tail = 0;

    printf("创建成功 \n");

    return Q;
}

int queue_empty(SeqQueuePtr Q)
{
    return Q->tail == Q->front;
}

int queue_full(SeqQueuePtr Q)
{
    return (Q->tail+1)%MAX == Q->front;
}

void queue_push(SeqQueuePtr Q ,datatype e)
{
    if (NULL == Q || queue_full(Q))
    {
        return;
    }
    
    Q->data[Q->tail] = e;

    Q->tail = (Q->tail+1)%MAX;

    return;
}

void queue_show(SeqQueuePtr Q)
{
    if (NULL == Q)
    {
        return;
    }

    printf("遍历结果:");
    for (int i = Q->front; i !=Q->tail; i=(i+1)%MAX)
    {
        printf("%d\t",Q->data[i]);
    }
    putchar(10);
    return;
}

void queue_pop(SeqQueuePtr Q)
{
    if (NULL == Q || queue_empty(Q))
    {
        return;
    }
    
    printf("%d 出队\n",Q->data[Q->front]);

    Q->front = (Q->front+1)%MAX;
}

int queue_size(SeqQueuePtr Q)
{
    if (NULL == Q)
    {
        return -1;
    }

    //不使用循环求大小

    int size = ((Q->tail-Q->front)+MAX)%MAX;

    return size;
}

void queue_destroy(SeqQueuePtr Q)
{
    if (NULL != Q)
    {
        free(Q);
        Q = NULL;
    }
    
    printf("boom!!\n");

    return;
}



main.c

#include "dui_lie.h"
int main(int argc, char const *argv[])
{
    SeqQueuePtr Q = queue_create();
    if (NULL == Q)
    {
        return -1;
    }

    queue_push(Q,90);
    queue_push(Q,80);
    queue_push(Q,100);
    queue_push(Q,20);
    queue_show(Q);

    queue_pop(Q);
    queue_pop(Q);
    queue_show(Q);

    printf("数组实际大小为%d:\n",queue_size(Q));

    queue_destroy(Q);
    return 0;
}

链式队列

链式存储的队列称为链式队列

实现原理:
        单向链表头插尾删实现:链表的头部就是队尾,链表的尾部就是队头                                

        单向链表头删尾插实现:链表的头部就是队头,链表的尾部就是队尾

        但是,上述操作中,都要用到链表尾部节点,都需要遍历整个链表完成,于是专门使用一个指针指向队尾,称为尾指针

00.h

#ifndef DAY17_1
#define DAY17_1

#include <myhead.h>

//类型重定义
typedef int datatype;

//节点结构体
typedef struct Node
{
    union 
    {
        datatype data;
        int len;
    };
    
    struct Node *next;
    
}Node, *NodePtr;

//头节点结构体
typedef struct Queue
{
    NodePtr head;
    NodePtr tail;

}Queue, *QueuePtr;

//队列创建
QueuePtr queue_create();

//判空
int queue_empty(QueuePtr Q);

//头插
int queue_push(QueuePtr Q,datatype);

//遍历
int queue_show(QueuePtr Q);

//出队
int queue_pop(QueuePtr Q);

//输出实际大小
int queue_size(QueuePtr Q);

//销毁
void queue_destroy(QueuePtr Q);

#endif // DAY17_1

00.c

#include "00.h"

//先创建队列 然后创建链表,将队列的两个指针指向链表
QueuePtr queue_create()
{
    //申请队列的空间
    QueuePtr Q = (QueuePtr)malloc(sizeof(Queue));
    if (NULL == Q)
    {
        printf("创建失败\n");
        return NULL;
    }

    //创建链表
    Q->head = (NodePtr)malloc(sizeof(Node));

    if (Q->head == NULL)
    {
        printf("创建失败\n");
        free(Q);
        return NULL;
    }

    Q->head->len = 0;
    Q->head->next = NULL;
    
    Q->tail = Q->head;

    return Q;
}


int queue_empty(QueuePtr Q)
{
    return Q->head->len == 0;
}

int queue_push(QueuePtr Q,datatype e)
{
    if (NULL == Q)
    {
       return -1;
    }

    NodePtr p = (NodePtr)malloc(sizeof(Node));
    if (NULL == p)
    {
        return -1;
    }
    
    p->data = e;
    p->next = NULL;

    Q->tail->next = p;

    Q->tail = p;

    Q->head->len++;
    
}

int queue_show(QueuePtr Q)
{
    if (NULL == Q || queue_empty(Q))
    {
        return -1;
    }
    NodePtr q = Q->head->next;

    while (q)
    {
        printf("%d\t",q->data);

        q = q->next;
    }
    putchar(10);
}

int queue_pop(QueuePtr Q)
{
    if (NULL == Q)
    {
        return -1;
    }
    

    NodePtr p = Q->head->next;
    Q->head->next = p->next;
    printf("%d 出队\n",p->data);
    free(p);
    p = NULL;

    //如果所有节点都出列成功,将尾节点重新指向头节点
    if (Q->tail == NULL)//Q->head->next == NULL
    {
        Q->tail = Q->head;
    }
    

    Q->head->len--;
}

int queue_size(QueuePtr Q)
{
    if (NULL == Q)
    {
        return -1;
    }
    
    return Q->head->len;
}

void queue_destroy(QueuePtr Q)
{
    if (NULL == Q)
    {
        return;
    }
    
    //释放所有节点
    while (!queue_empty(Q))
    {
        queue_pop(Q);
    }
    
    //释放头结点
    free(Q->head);
    Q->head = Q->tail = NULL;

    //释放队列空间
    free(Q);
    Q = NULL;
}

main.c

#include "00.h"

int main(int argc, char const *argv[])
{
    QueuePtr Q = queue_create();
    if (NULL == Q)
    {
        return -1;
    }
    queue_push(Q,233);
    queue_push(Q,1314);
    queue_push(Q,520);

    queue_show(Q);

    queue_pop(Q);
    queue_pop(Q);
    queue_pop(Q);
    
    queue_destroy(Q);

    return 0;
}

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

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

相关文章

免费【2024】springboot 成都奥科厨具厂产品在线销售系统设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

将手机作为服务器运行docker服务

前言 目前手机的配置并不低&#xff0c;即使是2019年生产的一加七Pro&#xff0c;配置也有12256&#xff0c;CPU是骁龙855&#xff0c;作为服务器运行着配置绰绰有余了&#xff0c;二手的价格现在是400左右也能接受。相对于是自带ups电源的便携低耗docker服务器&#xff0c;还…

C++ unordered_map与unordered_set的模拟实现

目录 0.前言 1.哈希表&#xff08;HashTable&#xff09;设计 1.1设计思想 1.2 HashTable.h 1.3设计思路 2.unordered_map封装 2.1 UnorderedMap.h 2.2代码解释 2.3测试函数 3.unordered_set封装 3.1 UnorderedSet.h 3.2代码解释 3.3测试函数 4.结语 &#xff08;图像由AI生成&…

项目打包与运行

前端运行时必须有与后端相同的数据库版本&#xff0c;数据库账号密码 右侧maven -> 展开要打包的项目 -> 生命周期 -> 双击package 打包好之后在target目录下 右键打开 在资源目录下输入cmd&#xff0c;执行以下命令即可运行&#xff08;端口号为yml文件…

人流量为王:背后的赚钱密码深度解析

在当今商业世界中&#xff0c;“人流量为王”这一理念被广泛认可和奉行。但你是否认真思考过&#xff0c;这简单的四个字背后&#xff0c;究竟隐藏着怎样复杂而精妙的赚钱逻辑&#xff1f; 一、人流量意味着潜在客户的聚集 想象一下繁华的商业街&#xff0c;熙熙攘攘的人群穿梭…

7月26日JavaSE学习笔记

反射 Java是面向对象的&#xff0c;有对象必须先有类&#xff0c; 有static修饰类的属性和方法&#xff1b;在Java中存储了类的内容&#xff0c;这个内容也应该是一个对象&#xff1b;Java中每一个用到的类都会加载一块内存&#xff0c;这每一块内存都是一个对象&#xff1b;这…

学习周报:文献阅读+HEC RAS案例

目录 摘要 Abstract 文献阅读&#xff1a;通过HEC RAS软件为罗马尼亚布加勒斯特市的Dmbovița河水管理的水力模型 文献摘要 讨论|结论 理论知识 边界条件计算 流量计算方式 曼宁公式 (Mannings Equation) 连续性方程 (Continuity Equation) 能量方程 (Energy Equatio…

EB Tresos 基于S32K3芯片 ICU模块实现gpio外部中断配置[后续更新实现icu模块的其他功能]

环境&#xff1a;eb tresos 27.0.1 port 模块配置&#xff1a; 选择一个具有erq功能的引脚并配置为erq功能。如下我选择的是 PTB0 -EIRQ[8] - SIUL2_EXT_IRQ_8_15_ISR Platform 模块配置 在这个模块中配置中断的开关以及中断句柄 ICU模块配置 具体配置参考博客&#xff1a;…

【python】python大学排名数据抓取+可视化(源码+数据集+可视化+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

深度强化学习 ②(DRL)

参考视频&#xff1a;&#x1f4fa;王树森教授深度强化学习 前言&#xff1a; 最近在学习深度强化学习&#xff0c;学的一知半解&#x1f622;&#x1f622;&#x1f622;&#xff0c;这是我的笔记&#xff0c;欢迎和我一起学习交流~ 这篇博客目前还相对比较乱&#xff0c;后面…

黑马Java零基础视频教程精华部分_5_面向对象综合练习

系列文章目录 文章目录 系列文章目录一、文字版格斗游戏二、文字版格斗游戏进阶版三、对象数组练习1、对象数组1先学习一下键盘录入。注意&#xff1a;两套体系不能混用 对象数组2对象数组3对象数组4对象数组5 一、文字版格斗游戏 GameTes.javat代码如下&#xff1a; package …

[数通网络基础]——广播域与路由器

广播域 广播域概述 广播域是指网络中能接收到同一广播消息的所有设备的集合。 广播域的大小会影响网络的性能和效率。当同一个广播域内广播报文过多时&#xff0c;会对局域网造成干扰&#xff0c;导致网络延迟&#xff0c;网络拥塞&#xff08;上网卡&#xff0c;上网慢&…

hot100-3滑动窗口

3无重复字符得最长字串 438找出字符串中得所有字母异位词 遇到没有限制字母排列方式的&#xff0c;都可以考虑维护一个charCode数组 和第567题相似 567字符串得排列&#xff08;和438一个思路&#xff09;

docker dotnet-dump离线部署

1.下载指定dotnet版本的dotnet-dump 示例地址&#xff1a; https://www.nuget.org/packages/dotnet-dump/3.1.141901#dependencies-body-tab 我本地测试的是netcore 3.1 2. 在本地解压 将文件解压出来。看到any目录,能看到我们要用的dotnet-dump文件 3. 将tools/netcoreapp2.…

AccessLog| 一款开源的日志分析系统

前言 ClkLog作为分析系列产品中的前端数据分析系统&#xff0c;通过采集前端应用数据进行用户行为分析。其社区版从23年9月发布至今已有近一年&#xff0c;商业版也上线快半年&#xff0c;感谢大家一直以来的关注和支持&#xff0c;ClkLog会继续做好产品升级与服务&#xff0c;…

算法-----递归~~搜索~~回溯(宏观认识)

目录 1.什么是递归 1.1二叉树的遍历 1.2快速排序 1.3归并排序 2.为什么会用到递归 3.如何理解递归 4.如何写好一个递归 5.什么是搜索 5.1深度&#xff08;dfs&#xff09;优先遍历&优先搜索 5.2宽度&#xff08;bfs&#xff09;优先遍历&优先搜索 6.回溯 1.什…

微信小游戏之 三消(一)

首先设定一下 单个 方块 cell 类&#xff1a; 类定义和属性 init 方法 用于初始化方块&#xff0c;接收游戏实例、数据、宽度、道具类型和位置。 onWarning 方法 设置警告精灵的帧&#xff0c;并播放闪烁动作&#xff0c;用于显示方块的警告状态。 grow 方法 根据传入的方向…

【科研技巧】如何查找一个人发表的所有文章

使用此网站 点击作者检索 点击作者名字 可以看到全部文章

SpringBoot运行流程源码分析

run方法核心流程 我们在启动SpringBoot的时候调用的是SpringApplication类的静态run方法。其核心流程如下图所示&#xff1a; 在run方法内完成了SpringApplication的声明周期。&#xff0c;这个过程涉及的几个核心类如下&#xff1a; SpringApplicationRunListeners&#xff…

【C++】:红黑树的应用 --- 封装map和set

点击跳转至文章&#xff1a;【C】&#xff1a;红黑树深度剖析 — 手撕红黑树&#xff01; 目录 前言一&#xff0c;红黑树的改造1. 红黑树的主体框架2. 对红黑树节点结构的改造3. 红黑树的迭代器3.1 迭代器类3.2 Begin() 和 End() 四&#xff0c;红黑树相关接口的改造4.1 Find…