当前位置: 首页 > news >正文

数据结构----队列

一、队列

1)队列定义

        队列(Queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。 允许插入的端是队尾,允许删除的端是队头。队列是一个先进先出(FIFO)的线性表,相应 的也有顺序存储和链式存储两种方式。

2)循环队列

        顺序存储就是用数组实现,比如有一个n个元素的队列,数组下标0的一端是队 头,入队操作就是通过数组下标一个个顺序追加,不需要移动元素,但是如果删除 队头元素,后面的元素就要往前移动,对应的时间复杂度就是O(n),性能自然不 高。

        为了提高出队的性能,就有了循环队列,需要有两个指针,front指向队头,rear指 向对尾元素的下一个位置,元素出队时front往后移动,如果到了对尾则转到头部, 同理入队时rear后移,如果到了对尾则转到头部,这样通过下标front出队时,就不 需要移动元素了。

         同时规定,当队列为空时,front和rear相等,那么队列什么时候判断为满呢?按照 循环操作rear依次后移,然后再从头开始,也是出现rear和front相等时,队列满。

        这样跟队列空的情况就相同了,为了区分这种情况,规定数组还有一个空闲单元 时,就表示队列已满, (也就是队头指针在队尾指针的下一位置时,队满。) 因为rear 可能在front后面,也可能循环到front前面,所以队列满的条件就变成了 (rear+1)%maxsize == front 。 对于队列的元素个数计算为:(rear -front+maxsize)%maxsize。

3)用数组实现的顺序存储循环队列

4)   链式队列

        循环队列要事先申请好空间,整个过程都不能释放,而且要有固定的长度,如果长度事先无法估计,这种方式显然不够灵活;所以就引入了链式存储队列,其实就是 线性表的单链表,只是它只能对尾进,队头出。并且规定队头指针指向链队列的头结点,对尾指针指向终端节点,当队列为空时,front和rear都指向头结点。(尾插头删)

        入队操作,就是在链表尾部插入结点;出队操作就是头结点的后继结点出队,然后将头结点的后继后移。如果最后除了头结点外,只剩一个元素了,就把rear也指向头结点。

二、队列的操作步骤

1.构建静态数组队列结构

1)建立结构体

2)初始化队列

3)入队

4)出队

5)遍历

#include<stdio.h>
#include <stdlib.h>
#include  <string.h>
#include<stdbool.h>
#include<assert.h>//静态数组构建队列结构
#define SIZE  5
typedef  int ele_type;typedef struct queue
{ele_type arr[SIZE];int front;int real;
}  Queue;//初始化队列
void init(Queue* que)
{assert(que);memset(que->arr, 0, sizeof(ele_type) * SIZE);que->front = 0;que->real = 0;
}//插入元素--入队
bool  push_queue(Queue* que, ele_type val)
{assert(que);if ((que->real + 1) % SIZE == que->front)return false;que->arr[que->real] = val;que->real++;que->real = que->real % SIZE;return true;}//删除元素--出队
bool  pop_queue(Queue* que, ele_type* rtval)
{assert(que);if (que->front == que->real)return false;*rtval = que->arr[que->front++];que->front = que->front % SIZE;return true;}//遍历队列
void print_queue(Queue* que)
{if (que->front == que->real)return;if (que->front < que->real){for (int i = que->front; i < que->real; i++){printf("%d\n", que->arr[i]);}}else{for (int i = que->front; i < SIZE; i++){printf("%d\n", que->arr[i]);}for (int i = 0; i < que->real; i++){printf("%d\n", que->arr[i]);}}}//获取数组长度
int get_queue_size(Queue* que)
{return ((que->real - que->front + SIZE) % SIZE);}//清空数组
void Clear_queue(Queue* que)
{que->front = que->real = 0;}int main()
{Queue q;init(&q);push_queue(&q, 11);push_queue(&q, 12);push_queue(&q, 13);push_queue(&q, 14);ele_type temp;pop_queue(&q, &temp);printf("temp=%d\n", temp);pop_queue(&q, &temp);printf("temp=%d\n", temp);pop_queue(&q, &temp);printf("temp=%d\n", temp);push_queue(&q, 15);push_queue(&q, 16);printf("===================\n");print_queue(&q);printf("ele num=%d\n", get_queue_size(&q));return 0;
}

运行结果:


2.构建链表队列结构

1)建立结构体

2)初始化队列

3)入队

4)出队

5)遍历

#include<stdio.h>
#include <stdlib.h>
#include  <string.h>
#include<stdbool.h>
#include<assert.h>//静态数组构建队列结构
#define SIZE  5
typedef  int ele_type;typedef struct queue
{ele_type arr[SIZE];int front;int real;
}  Queue;//初始化队列
void init(Queue* que)
{assert(que);memset(que->arr, 0, sizeof(ele_type) * SIZE);que->front = 0;que->real = 0;
}//插入元素--入队
bool  push_queue(Queue* que, ele_type val)
{assert(que);if ((que->real + 1) % SIZE == que->front)return false;que->arr[que->real] = val;que->real++;que->real = que->real % SIZE;return true;}//删除元素--出队
bool  pop_queue(Queue* que, ele_type* rtval)
{assert(que);if (que->front == que->real)return false;*rtval = que->arr[que->front++];que->front = que->front % SIZE;return true;}//遍历队列
void print_queue(Queue* que)
{if (que->front == que->real)return;if (que->front < que->real){for (int i = que->front; i < que->real; i++){printf("%d\n", que->arr[i]);}}else{for (int i = que->front; i < SIZE; i++){printf("%d\n", que->arr[i]);}for (int i = 0; i < que->real; i++){printf("%d\n", que->arr[i]);}}}//获取数组长度
int get_queue_size(Queue* que)
{return ((que->real - que->front + SIZE) % SIZE);}//清空数组
void Clear_queue(Queue* que)
{que->front = que->real = 0;}int main()
{Queue q;init(&q);push_queue(&q, 11);push_queue(&q, 12);push_queue(&q, 13);push_queue(&q, 14);ele_type temp;pop_queue(&q, &temp);printf("temp=%d\n", temp);pop_queue(&q, &temp);printf("temp=%d\n", temp);pop_queue(&q, &temp);printf("temp=%d\n", temp);push_queue(&q, 15);push_queue(&q, 16);printf("===================\n");print_queue(&q);printf("ele num=%d\n", get_queue_size(&q));return 0;
}

运行结果:

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • RabbitMq消息队列(缓存加速)
  • 登录过程记录
  • 讲解 狼人杀中的买单双是什么意思
  • php 在app中唤起微信app进行支付,并处理回调通知
  • mysql误删数据恢复记录
  • 判断 I2C 总线通信异常原因的方法2
  • HarmonyOS WebView
  • 学习STM32(6)-- STM32单片机ADCDAC的应用
  • NFS文件共享
  • Unity WebGL平台Hybrid Generate All报错undefined symbol sendfile
  • 大语言模型与多模态大模型loss计算
  • Gin框架接入pyroscope完美替代pprof实现检测内存泄露
  • 离职保密协议是什么?怎么样才是合法的?如何维护公司权益?
  • DataGear 企业版 1.2.0 发布,数据可视化分析平台
  • django常用的组合搜索组件
  • Apache的80端口被占用以及访问时报错403
  • C学习-枚举(九)
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • java概述
  • java小心机(3)| 浅析finalize()
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • node 版本过低
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • STAR法则
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • yii2中session跨域名的问题
  • 安卓应用性能调试和优化经验分享
  • 百度小程序遇到的问题
  • 工作中总结前端开发流程--vue项目
  • 基于webpack 的 vue 多页架构
  • 使用 @font-face
  • 小程序 setData 学问多
  • 小程序开发中的那些坑
  • 阿里云服务器如何修改远程端口?
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​iOS实时查看App运行日志
  • # 透过事物看本质的能力怎么培养?
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (7) cmake 编译C++程序(二)
  • (C语言)二分查找 超详细
  • (补)B+树一些思想
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (附源码)ssm基于web技术的医务志愿者管理系统 毕业设计 100910
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (四)汇编语言——简单程序
  • (五)MySQL的备份及恢复
  • (转)Mysql的优化设置
  • (转)菜鸟学数据库(三)——存储过程
  • (转载)Linux网络编程入门
  • .gitignore文件_Git:.gitignore