数据结构十——队列

文章出处:极客时间《数据结构和算法之美》-作者:王争。该系列文章是本人的学习笔记。

1 队列

队列:可以想象成排队买票,先来的人先买,后到的人站在队尾。先进者先出,这就是队列。

队列的操作:入队(enqueue)、出队(dequeue)。入队:在队列尾部添加一个元素。出队:在队列头部移除一个元素。

2 队列的实现

队列的实现可以用数组,也可以用链表,分别称为顺序队列、链式队列。

2.1 基于数组的实现

public class ArrayQueue {private String[] items;private int n = 0;private int head;private int tail;public ArrayQueue(int capacity){this.n = capacity;items = new String[this.n];head = tail = 0;}/*** 在队尾插入一个元素* @param value* @return*/public  boolean enqueue(String value){if(tail >=n) return false;//超出容量items[tail] = value;tail++;return true;}/*** 出队:从对头删除一个元素* @return*/public String dequeue(){if(head==tail) return null;String ret = items[head];head++;return ret;}
}

举个 例子,画画图可以发现,随着入队、出队操作,head、tail指针不断向右移动,极端情况是head、tail都在右边,即使数组有空间,也不能再做入队操作。

如何解决这个问题呢?我们可以在不能入队的时候,将head、tail之间的元素,拷贝到[0,tail-head]之间。

	public  boolean enqueue(String value){if(tail==n){if(head==0) return false;for(int i=head;i<tail;i++){items[i-head] = items[i];}tail = tail-head;head = 0;}items[tail] = value;tail++;return true;}

在这个版本实现中,出队操作时间复杂度是O(1),入队时间复杂度是多少呢?直觉认为平均时间复杂度应该还是O(1)。无证明。

2.2 基于链表的实现

需要两个指针head、tail分别指向队列头部、队列尾部。入队的时候tail.next=new node,tail=tail.next;出队的时候,head=head.next。
代码

3 循环队列

3.1 数组实现

在2.1基于数组实现的队列中有数据迁移的操作。如果是一个循环队列就不需要数据迁移操作了。循环队列是指它长的像一个环,原本队列头部、和队列尾部形成一条直线。现在把队列头部和队列尾部扳成了一个环。

图中队列长度为8,head=4,tail=7。
当插入a的时候,items[7]=a,tail=(tail+1)%8=0。
当插入b的时候,items[0]=b,tail=(tail+1)%8=1。

通过这样的方式,就避免了数据搬移的工作。
循环队列的实现重点是判断什么时候为空,什么时候队列已满,不能再添加数据。
在一般队列中,当head=tail的时候,队列为空。循环队列也是。
在一般队列中,当tail=n的时候,队列已满,不能再添加数据。循环队列需要多举几个例子,画图总结规律。

图中head=4,tail=3,数组长度len=8。如果再插入数据tail=(tail+1)%8=head,tail=head,这与队列为空的条件重复了。所以,我们在(tail+1)%8=head的时候后,就不再插入数据。也就是说items[tail]是没有值的。
代码

3.2 基于链表实现

基于链表实现就更简单了,将tail.next=head即可。

4 并发队列和阻塞队列

阻塞队列就是在队列的基础上加了阻塞的操作。例如当队列为空的时候,在队列头部取数据的时候会进入阻塞状态,直到队列中有数据的时候才返回数据。当队列满了的时候,往队列中插入数据的时候会进入阻塞状态,直到队列中有空间存储数据的时候才入队成功,然后返回。
在这里插入图片描述
其实,这就是一个生产者-消费者模型。

这种生产者消费者模型可以有效协调生产速度和消费速度。例如当生产者生产速度过快,消费者来不及消费的情况下,生产者很快会填满队列,生产者进入阻塞状态,只有当消费者消费之后,有了剩余空间,生产者才能继续生产。

不仅如此,我们开可以分配1个生产者,多个消费者。
在这里插入图片描述

在多线程情况下就会存在线程安全问题。如何实现一个线程安全的队列呢?线程安全的队列被称为并发队列。用CAS,可以实现一个高效地安全队列。

5 队列应用在有限资源的场景下

队列主要应用在资源有限的场景下。例如数据库连接池里的连接是有限的,服务器每秒能处理的请求量是有限的。

当服务器的请求池中有空闲的服务线程的时候,我们希望公平地处理每一个到访的请求。这个时候我们将请求加入到队列中。当服务器的请求池中有空闲服务线程的时候,从队列取请求,进行服务。

队列的实现有两种方式:数组和链表。链表实现的队列可以无限扩容,可以接受无限的请求,但这容易引起内存溢出。数组实现的队列只能接受一定个数的请求,超出数量,直接返回无法访问。但是队列大小的设定需要权衡用户体验以及服务器的内存大小。

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

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

相关文章

[教程]博客园插入视频教程

【学习观15】人类为啥不进化成过目不忘&#xff1f;记忆力差难道不阻碍学习吗&#xff1f; 代码 <div class"video"> <iframe src"//player.bilibili.com/player.html?aid54874176&cid95969626&page1" scrolling"no" border&q…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第34篇]描述攻击离散对数问题的baby-step/Giant-step方法

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 Baby-step/Giant-step是Dnaiel Shanks为解决DLP问题开发的算法。DLP问题已经是许多现代密码学的困难性基础。…

spring学习(15):required属性

CompactDisc类 package soundSystem;import org.springframework.stereotype.Component; //注解Componentpublic class CompactDisc {public CompactDisc() {super();System.out.println("compactdisc无参构造方法");}public void play(){System.out.println("…

爬虫的单线程+多任务异步协程:asyncio 3.6

单线程多任务异步协程:asyncio 3.6 事件循环 无限循环的对象.事件循环中最终需要将一些 特殊的函数(被async关键字修饰的函数) 注册在该对象中.协程 本质上是一个对象.可以把协程对象(特殊的函数)注册到事件循环中任务对象 就是对协程对象进一步的封装.绑定回调: task.add_done…

算法十——深度优先搜索和广度优先搜索

文章出处&#xff1a;极客时间《数据结构和算法之美》-作者&#xff1a;王争。该系列文章是本人的学习笔记。 搜索算法 算法是作用于数据结构之上的。深度优先搜索、广度优先搜索是作用于图这种数据结构之上的。图上的搜索算法可以理解为从一个顶点到另外一个顶点。 常用的搜…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol 52][第35篇]给针对ECDLP问题的Pollard rho,parallel Pollard rho攻击的一个粗略的描述

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 [1] http://www.cs.bris.ac.uk/~nigel/Crypto_Book/book.ps (pages 208 - 214) 转载连接&#xff1a;https…

spring学习(16):使用接口

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

交易系统高并发下的幂等性设计原则

一、介绍 幂等性就是针对同一个请求&#xff0c;不管该请求被提交了多少次&#xff0c;该请求都将被视为同一个请求&#xff0c;服务端不应该将同一个请求进行多次处理&#xff0c;以确认处理逻辑的正确性&#xff0c;针对交易性系统幂等性的设计尤为重要&#xff0c;否则由于网…

工程中选择数据结构和算法的依据

1. 时间、空间复杂度不能和性能划等号 时间、空间复杂度不是时间执行和内存消耗的精确值。它们只是表示了随着数据量的增长&#xff0c;时间、空间的增长趋势。 代码的执行时间有时不跟时间复杂度成正比。我们常说算法是O(nlogn),O(n2n^2n2)这些都是基于大数据量&#xff08;…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第36篇]Index Calculus算法

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 我们这篇博客继续描述一种数学攻击&#xff0c;这种数学攻击被叫做Index Calculus(IC)算法。 注意这里Index…

DS博客作业07--查找

1.本周学习总结 1.思维导图 2.谈谈你对树结构的认识及学习体会。 查找是一种跟我们生活息息相关的算法&#xff0c;最典型的例子就是搜索引擎&#xff0c;而评价一种查找算法的优劣的关键就是查找速度&#xff0c;生活中我们往往要在大量数据查找自己所需要的东西&#xff0c;如…

easyUI学习笔记二

1&#xff0e; 拖拉大小 <!DOCTYPE html> <html> <head><title>easyui学习</title><script type"text/javascript" src jquery-easyui/jquery.min.js> </script><script type"text/javascript" src jquer…

C语言—每日选择题—Day62

隔一天更新解析 第一题 1. 在使用标准C库时&#xff0c;下面哪个选项使用只读模式打开文件&#xff1f; A&#xff1a;fopen("foo.txt", "r") B&#xff1a;fopen("foo.txt", "r") C&#xff1a;fopen("foo.txt", "w&…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第37篇]The Number Field Sieve

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 转载链接&#xff1a;https://www.cnblogs.com/zhuowangy2k/p/12245636.html

大二下学期软件工程概论总结

软件工程概论这门课可以算是我本学期最辛苦的一门课了。但与此同时这门课给我带来的收获和其他课程相比&#xff0c;也不是一个量级的。 这学期我通过课上的学习与作业项目的完成过程&#xff0c;了解到软件开发由项目的确定到项目的需求分析&#xff0c;再到概要&#xff0c;详…

70. Climbing Stairs

输入&#xff1a;台阶数量n 输出&#xff1a;有多少种走法 规则&#xff1a;每次可以上一个台阶或者两个台阶 分析&#xff1a;想明白一件事情。如果现在在第k个台阶&#xff0c;那下一步可以到达第k1个台阶&#xff0c;或者第k2个台阶。换句话说想要到达第k个台阶&#xff0c;…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第39篇]侧信道攻击和故障攻击有什么区别

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 侧信道攻击(Side-channel attacks, SCA)是一类攻击者尝试通过观察侧信道泄露来推测目标计算的信息。&#x…

面向对象:包装类、对象处理、类成员

包装类 Java是面向对象编程语言&#xff0c;但也包含了八种基本的数据类型&#xff0c;这八种基本的数据类型不支持面向对象的编程机制&#xff0c;基本的数据类型也不具备对象的特性&#xff1a;没有成员变量、方法被调用。所有类型的变量都继承Object类&#xff0c;都可以当成…

mysql-安装报错计算机中丢失MSVCR100.dll文件丢失

https://blog.csdn.net/weirdo_world/article/details/82393330

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol52]40一般来说SPA和DPA的区别是什么

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 电磁(Electronmagnetic, EM)功率分析攻击被划分成两种类型的攻击&#xff0c;简单功率分析(SPA)或者差分功率…