常见数据结构-队列先进先出
一,概述
队列这个概念非常好理解。你可以把它想象成排队买票,先来的先买,后来的人只能站末尾,不允许插队。先进者先出,这就是典型的“队列”。
二,顺序队列和链式队列
队列和栈一样,也是一种抽象的数据结构,操作上具有“先进先出”的特性,队列只允许在"队首"进行删除操作,而在"队尾"进行插入操作。基于数组实现的顺序队列的C++
代码如下:
// 用数组实现的队列
class ArrayQueue(){// 数组:items,数组大小:n
private:int n = 20;int head = 0; // 队头下标int tail = 0; // 队尾下标public:// 带参数的构造函数:申请一个大小为 capacity 的数组ArrayQueue(int capacity){// items = new int[capacity];vector<int> items(capacity);n = capacity;}// 入队bool enqueue(int item){if(tail == n) return False;items[tail] = item;++tail;return True;}// 时间复杂度为O(1)的入队操作bool enqueue2(int item){// tail == n,表示队列末尾没有空间了if(tail == n){// tail == n && head == 0,表示整个队列都占满了if(head == 0) return False;// 数据搬移for(i=head; i<tail; ++i){items[i-head] = items[i];}// 重新更新 head 和 tailtail = tail - head; // tail -= headhead = 0; // 队首位置}items[tail] = item;++tail;return True;}// 出队bool dequeue(){// head == tail 表示队列为空if (head == tail) return null;int ret = items[tail];++head;return ret;}
}
入队时间复杂度为 O(1)
。分析:大部分情况下入队操作时间复杂度为 O(1)
,只有在 tail
在末尾时( tail=n
)才进行数据迁移,此时的入队操作时间复杂度为 O(n)
,根据均摊时间复杂度得到入队时间复杂度为 O(1)
。
三,循环队列
前面用数组实现队列,当 tail = n
时,会有数据搬移操作。循环队列首尾相连,用数组实现循环队列代码的关键在于判断队列满和空的条件。
- 非循环队列:
- 队满:
tail = n
- 队空:
head = tail
- 队满:
- 循环队列:
- 队满:
(tail + 1) % n = head
- 队空:
head = tail
- 队满:
基于数组实现的循环队列的C++
代码如下:
// 用数组实现的循环队列,关键在于创建队头和队尾下标
class CircularQueue(){private:int n = 12;int items[];// head表示队头下标,tail表示队尾下标int head = 0;int tail = 0;
public:CircularQueue(int capacity){// items = new int[capacty];vector<int> items(capacity);n = capacity;}// 入队函数bool enqueue(int item){// 队列满了if((tail+1)%n = head) return False;items[tail] = item;tail = (tail + 1) % n}// 出队函数int dequeue(){// // 如果head == tail 表示队列为空if(head == tail) return null;int ret = items[head];head = (head + 1) % n;return ret;}
}
四,阻塞队列和并发队列
- 阻塞队列就是入队、出队操作都可以阻塞,简单来说就是队列为空时,队首取数据会被阻塞,队列为满时,队尾插入数据会被阻塞,直到队列有空闲数据才允许在队尾插入数据。使用阻塞队列结构可以轻松实现“消费者-生产者模型”。
- 并发队列就是队列的操作多线程安全。最简单直接的实现方式是直接在
enqueue()、dequeue()
方法上加锁,但是锁粒度大并发度会比较低,同一时刻仅允许一个存或者取操作。实际上,基于数组的循环队列,利用CAS
原子操作,可以实现非常高效的并发队列。这也是循环队列比链式队列应用更加广泛的原因。
参考资料
《数据结构与算法之美》-队列
常见数据结构-队列先进先出相关推荐
- 数据结构队列-先进先出
一,概述 队列这个概念非常好理解.你可以把它想象成排队买票,先来的先买,后来的人只能站末尾,不允许插队.先进者先出,这就是典型的"队列". 二,顺序队列和链式队列 队列和栈一样,也 ...
- 数据结构-队列-“先进先出”的数据结构
1.队列是线性表的一种,在操作数据元素时,和栈一样,有自己的规则:使用队列存取数据元素时,数据元素只能从表的一端进入队列,另一端出队列 2.队列的顺序表示和实现 使用顺序存储结构表示队列时,首先申请足 ...
- 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)
常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...
- Java笔记整理五(Iterator接口,泛型,常见数据结构(栈,队列,数组,链表,红黑树,集合),jdk新特性,异常,多线程,Lambda表达式)
Java笔记整理五 1.1Iterator接口 Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象 ...
- 简单数据结构(队列 栈 树 堆 )
基础知识 基本概念 程序 = 算法 + 数据结构数据结构是计算机存储.组织数据的方式.数据结构是指相互之间存在一种或多种特定关系的数据元素的集合.通常情况下,精心选择的数据结构可以带来更高的运行或者存 ...
- 获取用户列表为空_数据结构和算法(Golang实现)(15)常见数据结构-列表
列表 一.列表 List 我们又经常听到 列表 List 数据结构,其实这只是更宏观的统称,表示存放数据的队列. 列表 List:存放数据,数据按顺序排列,可以依次入队和出队,有序号关系,可以取出某序 ...
- java 数据结构_Java版-数据结构-队列(数组队列)
前言 看过笔者前两篇介绍的 Java版数据结构 数组和 栈的盆友,都给予了笔者一致的好评,在这里笔者感谢大家的认可!!! 由于本章介绍的数据结构是 队列,在队列的实现上会基于前面写的 动态数组来实现, ...
- 图解!24 张图彻底弄懂九大常见数据结构!
作者 | Amazing10 责编 | 屠敏 数据结构想必大家都不会陌生,对于一个成熟的程序员而言,熟悉和掌握数据结构和算法也是基本功之一.数据结构本身其实不过是数据按照特点关系进行存储或者组织的集合 ...
- 数据结构软件测试,资讯详情-java常见数据结构-柠檬班-自动化测试-软件测试培训-自学官网...
Java中常见数据结构 1.LinkedList 双向链表 特点: 1. 物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现 每个元素包含三个节点,一个是存储元素的数据 ...
最新文章
- 深入理解Java:类加载机制及反射
- java框架核心技术_你必须掌握的 21 个 Java 核心技术!(干货)
- 边界化难题终结者!将自监督学习应用到自动驾驶上 | CVPR 2021
- eager_EAGER的获取是代码的味道
- koa mysql mongodb_koa 操作MongoDB数据库
- ruby三元操作符_在Ruby中使用操作符将元素添加到数组实例中
- AOP日志组件 多次获取post参数
- 5%和1%精度的贴片电阻标称阻值表
- unity下载与安装
- 面试官问我:多个 List 如何取交集、并集、去重并集、差集?
- html5hr标签默认值,hr_标签 | Elements_HTML_参考手册_非常教程
- 洛谷 P3620 - P3621 数据备份、风铃、动物园(APIO 2007)
- swift学习笔记之navigationController的设置以及使用
- 车联网安全知识点总结
- php 文字弹幕效果代码,视频弹幕特效代码
- 盛金公式(一元三次方程的解)
- 为什么嵌入式 IoT 设备优先选择 RTOS 而不是Linux ?
- Java实现生成可跳转指定页面的二维码
- Python | 编辑器推荐:Jupyter
- Swift入门第一天(踩坑)