数据结构(六)队列

文章目录

  • 一、概念
  • 二、逻辑结构:线性结构
  • 三、存储结构
    • (一)顺序队列
    • (二)循环队列
      • 1. 结构体定义
      • 2. 创建队列
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 3. 入队列
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 4. 出队列
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 5. 清空和销毁
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 6. 打印
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
    • (三)链式队列
      • 1. 结构体定义
      • 2. 创建队列
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 3. 入队列
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 4. 出队列
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 5. 清空和销毁
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 6. 打印
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
  • 四、所有源代码已上传至我的资源

一、概念

队列是一种先入先出的结构(FIFO — first in first out)

二、逻辑结构:线性结构

三、存储结构

(一)顺序队列

顺序队列是基于 一个数组配合着两个下标(队列头front、队列尾rear)来实现的
顺序队列的本质就是对顺序表操作的一个约束:只能在一端插入 另一端删除
图片1

这种队列我们一般不直接使用,因为 入队列时rear++ 出队列时front++
相当于每块空间只使用了一次,即使数据出队列了,空间也不会被复用了,相当于一次性的队列

(二)循环队列

循环队列相当于顺序队列的一个小优化,目的是让空间复用起来
图片

这种队列就能让空间复用起来了。
每次数据入队列后,不要直接执行 rear++ 而是改成 rear = (rear+1)%N
每次数据出队列后,不要直接执行 front++ 而是改成 front = (front+1)%N

判断队列为空 front == rear ,如下图,即认为队列空
在这里插入图片描述

判断队列为满 (rear+1)%N == front (浪费了一个存储空间 方便区分队列满 和 队列空),如下图,即认为队列已满
在这里插入图片描述

1. 结构体定义

typedef struct _Queue{int s[N];int front;int rear;
}queue_t;

2. 创建队列

(1)函数定义

int create_queue(queue_t **my_queue);

(2)注意点
(3)代码实现
int create_queue(queue_t **my_queue){if(NULL==my_queue) return -1;*my_queue=(queue_t *)malloc(sizeof(queue_t));if(NULL==*my_queue) return -1;//初始化(*my_queue)->front=0;(*my_queue)->rear=0;return 0;
}

3. 入队列

(1)函数定义

int is_full(queue_t *my_queue);
int push_queue(queue_t *my_queue,int num);

(2)注意点
(3)代码实现
//满为1,空为0
int is_full(queue_t *my_queue){if(NULL==my_queue) return -1;return (my_queue->rear+1)%N==my_queue->front?1:0;
}//入队列
int push_queue(queue_t *my_queue,int num){if(NULL==my_queue) return -1;if(is_full(my_queue)){printf("队列满\n");return -1;}my_queue->s[my_queue->rear]=num;my_queue->rear=(my_queue->rear+1)%N;return 0;
}

4. 出队列

(1)函数定义

int is_empty(queue_t *my_queue);
int pop_queue(queue_t *my_queue,int num);

(2)注意点
(3)代码实现
//空为1,不空为0
int is_empty(queue_t *my_queue){if(NULL==my_queue) return -1;return my_queue->rear==my_queue->front?1:0;
}int pop_queue(queue_t *my_queue,int *num){if(NULL==my_queue || NULL==num) return -1;if(is_empty(my_queue)){printf("队列空\n");return -1;}*num=my_queue->s[my_queue->front];my_queue->front=(my_queue->front+1)%N;
}

5. 清空和销毁

(1)函数定义

int clean_queue(queue_t *my_queue)
int destroy_queue(queue_t **my_queue);

(2)注意点
(3)代码实现
int clean_queue(queue_t *my_queue){if(NULL==my_queue) return -1;my_queue->rear=my_queue->front;return 0;
}int destroy_queue(queue_t **my_queue){if(NULL==my_queue || NULL==*my_queue) return -1;free(*my_queue);*my_queue=NULL;return 0;
}

6. 打印

(1)函数定义

int print_queue(queue_t *my_queue);

(2)注意点
(3)代码实现
int print_queue(queue_t *my_queue){if(NULL==my_queue) return -1;/**也可以写成这种形式*for(int i=my_queue->front;i!=my_queue->rear;i=(i+1)%N){*	printf("%d ",my_queue->s[i]);*}**/int temp=my_queue->front;while(temp!=my_queue->rear){printf("%d ",my_queue->s[temp]);temp=(temp+1)%N;}putchar(10);return 0;
}

(三)链式队列

逻辑结构:线性结构
存储结构:链式存储,在内存中不连续

1. 结构体定义

//数据元素的结构体
typedef struct _Node{int data;struct _Node *next;
}node_t;//队列的结构体
typedef struct _Queue{node_t *front;node_t *rear;
}queue_t;

2. 创建队列

(1)函数定义

int create_queue(queue_t **my_queue);

申请一块数据对象的内存空间
初始化

(2)注意点
  1. 初始化时,front和rear指针均为NULL
(3)代码实现
int create_queue(queue_t **my_queue){if(NULL==my_queue) return -1;*my_queue=(queue_t *)malloc(sizeof(queue_t));if(NULL==*my_queue) return -1;//初始化(*my_queue)->front=NULL;(*my_queue)->rear=NULL;return 0;
}

3. 入队列

(1)函数定义

int push_queue(queue_t *my_queue,int num);

申请一块数据元素的内存空间
采用尾插

(2)注意点
  1. 插入第一个节点时,需要将front和rear都指向第一个节点
  2. 其他节点采用尾插的方法,front无需改变
(3)代码实现
//尾插,无需判断是否满
int push_queue(queue_t *my_queue,int num){if(NULL==my_queue) return -1;node_t *p=(node_t *)malloc(sizeof(node_t));if(NULL==p) return -1;p->next=NULL;p->data=num;//插入第一个节点if(NULL==my_queue->front){my_queue->front=p;my_queue->rear=p;return 0;}//插入其他节点,头节点不变my_queue->rear->next=p;my_queue->rear=p;return 0;
}

4. 出队列

(1)函数定义

int is_empty(queue_t *my_queue);
int pop_queue(queue_t *my_queue,int num);

(2)注意点
  1. 头删,需要判断队列是否为空,当my_queue->front为NULL时说明队列空
  2. 只有一个元素时,删除它时front和rear指针均需要置NULL
(3)代码实现
int is_empty(queue_t *my_queue){if(NULL==my_queue) return -1;return my_queue->front==NULL?1:0;
}
int pop_queue(queue_t *my_queue,int *num){if(NULL==my_queue||NULL==num) return -1;if(is_empty(my_queue)){printf("栈空\n");return -1;}//只有一个元素if(my_queue->front==my_queue->rear){*num=my_queue->front->data;free(my_queue->front);my_queue->front=NULL;my_queue->rear=NULL;return 0;}//有多个元素node_t *ptemp=my_queue->front;*num=my_queue->front->data;my_queue->front=my_queue->front->next;free(ptemp);ptemp=NULL;return 0;
}

5. 清空和销毁

(1)函数定义

int clean_queue(queue_t *my_queue)
int destroy_queue(queue_t **my_queue);

(2)注意点
  1. 清空是释放所有元素的节点空间
  2. 销毁是先清空,然后释放数据对象的空间
(3)代码实现
int clean_queue(queue_t *my_queue){if(NULL==my_queue) return -1;node_t *ptemp=NULL;while(my_queue->front!=NULL){ptemp=my_queue->front;my_queue->front=my_queue->front->next;free(ptemp);}ptemp=NULL;my_queue->rear=NULL;return 0;
}int destroy_queue(queue_t **my_queue){if(NULL==my_queue||NULL==*my_queue) return -1;clean_queue(*my_queue);free(*my_queue);*my_queue=NULL;return 0;
}

6. 打印

(1)函数定义

int print_queue(queue_t *my_queue);

(2)注意点
  1. 链式队列与顺序队列不同的一点是,链式队列的rear指向的是最后一个已存入数据的节点,顺序队列rear指向的是最后一个已存入数据的空间的下一个空间。
  2. 先打印除了最后一个节点以外所有节点,此时还有最后一个节点没打印
(3)代码实现
int print_queue(queue_t *my_queue){if(NULL==my_queue||NULL==my_queue->front) return -1;node_t *ptemp=my_queue->front;//打印除了最后一个节点之外所有节点while(ptemp!=NULL){printf("%d ",ptemp->data);ptemp=ptemp->next;}putchar(10);return 0;
}

四、所有源代码已上传至我的资源

下载链接:
C语言实现循环队列
C语言实现链式队列

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows内存管理

一 windows系统的内存管理涉及哪些 1.1 虚拟内存管理机制 windows操作系统使用虚拟内存技术,将磁盘文件,通过映射对象(存储在物理内存)关联,映射到虚拟内存作为文件试图。即用户操作"虚拟内存中File View Objec…

Android数据缓存框架 - 内存数据载体从LiveData到StateFlow

引言:所有成功者的背后,都有一份艰苦的历程,不要只看到了人前的风光,而低估了他们背后所付出的努力。 随着flow到流行度越来越高,有开发者呼吁我使用flow,于是我就如你们所愿,新增了StateFlow作…

Flink本地idea运行环境配置webui

Flink本地idea运行环境配置webui 1.添加依赖 <dependency><groupId>org.apache.flink</groupId><artifactId>flink-runtime-web_2.11</artifactId><version>1.13.6</version><scope>provided</scope></dependency&g…

【Qt Creator】跨平台的C++图形用户界面应用程序开发框架---QT

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 1.互联网的核心岗位以及职…

【Chapter5】死锁与饥饿,计算机操作系统教程,第四版,左万利,王英

文章目录 1.1 什么是死锁1.2 死锁的类型1.2.1 竞争资源引起的死锁1.2.2 进程间通信引起的死锁1.2.3 其他原因引起的死锁 1.3 死锁产生必要条件1.4 死锁的处理策略1.5 死锁的预防1.5.1 破坏资源独占条件1.5.2 破坏不可剥夺条件1.5.3 破坏保持申请条件1.5.4 破坏循环等待条件 1.6…

Spring Boot 统一数据返回格式

在 Spring Boot 项目中&#xff0c;统一的数据格式返回是一种良好的实践&#xff0c;它提高了代码的可维护性和一致性&#xff0c;并改善了客户端与服务端之间的通信。本文将介绍如何在 Spring Boot 中实现统一的数据格式返回。 1 为什么需要统一数据返回格式 ⽅便前端程序员更…

Reader类的使用方法和技巧,你掌握了吗?

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

vscode中使用conda虚拟环境

每一次配置环境&#xff0c;真的巨烦&#xff0c;网上的资料一堆还得一个个尝试&#xff0c;遂进行整理 1.准备安装好Anaconda 附带一篇测试教程&#xff0c;安装anaconda 2.准备安装vscode 安装地址&#xff1a;Visual Studio Code 3.创建Conda环境 搜索框搜索Anaconda…

音视频及H264/H256编码相关原理

一、音视频封装格式原理&#xff1a; 我们播放的视频文件一般都是用一种封装格式封装起来的&#xff0c;封装格式的作用是什么呢&#xff1f;一般视频文件里不光有视频&#xff0c;还有音频&#xff0c;封装格式的作用就是把视频和音频打包起来。 所以我们先要解封装格式&#…

香橙派OrangePi AIpro上手初体验

一、前言 非常感谢能够收到CSDN和香橙派的OrangePi AIpro开发板评测活动的邀请&#xff1b;收到的OrangePi AIpro实物如下所示&#xff1a; 二、OrangePi AIpro介绍 通过查询香橙派官网可以了解到OrangePi AIpro的相关信息如下&#xff1a;OrangePi AIPro 开发板是香橙派联合…

【在Postman中,如果后端返回的是String类型的数据但不是JSON格式,报错】

在Postman中&#xff0c;如果后端返回的是String类型的数据但不是JSON格式 问题描述解决办法 postman后端返回的String数据,不是json,怎么设置结果的接收&#xff1f; 问题描述 在postman中测试接口&#xff0c;报错Error&#xff1a;Abort&#xff0c;或者显示返回数据校验失…

C++入门——日期类的实现

前言 生活中&#xff0c;我们时不时会遇到算天数的问题&#xff1a;高考倒计时、考研倒计时、过年倒计时...... 想解决这些问题无非就是实现一个年月日的计算器&#xff0c;那要怎么来实现呢&#xff1f; 下面就让我们来探究一下。 1.了解日期计算器的需求 1.1 表面需求 …

Tailwind CSS快速入门

文章目录 初识安装Tailwindcss试用安装快速书写技巧扩展好处Todo 初识 只需书写 HTML 代码&#xff0c;无需书写 CSS&#xff0c;即可快速构建美观的网站 Tailwind CSS 是一个功能类优先的 CSS 框架&#xff0c;它通过提供大量的原子类&#xff08;utility classes&#xff09;…

FTP协议——LightFTP安装(Linux)

1、简介 LightFTP是一个轻量级的FTP&#xff08;File Transfer Protocol&#xff0c;文件传输协议&#xff09;客户端软件。FTP是一种用于在网络上传输文件的标准协议&#xff0c;允许用户通过TCP/IP网络&#xff08;如互联网&#xff09;在计算机之间进行文件传输。 2、步骤…

APM2.8下载固件的方法(两种办法详解)

1.把APM飞控用安卓手机的USB线插入电脑。 选择COM口&#xff0c;不要选择auto&#xff0c;如果你没有COM口说明你驱动安装有问题。 波特率115200。点击相应的图标就可以下载固件到飞控板。 请注意&#xff1a;烧录APM必须选择INSTALL FIRMWARE LEAGACY,第一个是用于刷pixhawk的…

常用时序逻辑电路模块:移位寄存器

寄存器与移位寄存器 寄存器&#xff1a;数字系统中用来存储二进制数据的逻辑器件。存储N位二进制数据的寄存器需要N个触发器组成。 移位功能&#xff1a;存储代码在脉冲作用下依次左移或右移。 移位寄存器&#xff1a; 移位寄存器中的数据可以在移位脉冲作用下依次逐位右移…

Vue3_创建项目

目录 一、创建vue项目 1.下载vue 2.进入刚才创建的项目 3.安装依赖 4.运行项目 ​5.打包项目放入生产环境 二、vue项目组成 1.项目文件结构 2.项目重要文件 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、C…

unity制作app(9)--拍照 相册 上传照片

1.传输照片&#xff08;任何较大的数据&#xff09;都需要扩展服务器的内存空间。 2.还需要base64编码 2.1客户端发送位置的编码 2.2服务器接收部分的代码

Visual Studio中调试信息格式参数:/Z7、/Zi、/ZI参数

一般的调试信息都保存在pdb文件中。 Z7参数表示这些调试信息保存到OBJ目标文件中&#xff0c;这样的好处是不需要单独分发PDB文件给下游。Zi就是把所有的调试信息都保存在pdb文件中&#xff0c;以缩小发布文件的大小。ZI和Zi类似&#xff0c;但是增加了热重载的能力&#xff1…

数据库|基于T-SQL向数据库数据表中添加、修改、删除数据

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 前边学习了基于T-SQL创建数据库和创建数据表&#xff0c; 《数据库|基于T-SQL创建数据库》 《数据库|基于T-SQL创建数据表》 接下来学习向创建好的数据表中添加数据&#xff0c;以下为学习笔记。 01 通过T-SQL向数据表…