网易首页 > 网易号 > 正文 申请入驻

看动画学算法之:队列queue

0
分享至

简介

队列Queue是一个非常常见的数据结构,所谓队列就是先进先出的序列结构。

想象一下我们日常的排队买票,只能向队尾插入数据,然后从队头取数据。在大型项目中常用的消息中间件就是一个队列的非常好的实现。

队列的实现

一个队列需要一个enQueue入队列操作和一个DeQueue操作,当然还可以有一些辅助操作,比如isEmpty判断队列是否为空,isFull判断队列是否满员等等。

为了实现在队列头和队列尾进行方便的操作,我们需要保存队首和队尾的标记。

先看一下动画,直观的感受一下队列是怎么入队和出队的。

先看入队:

再看出队:

可以看到入队是从队尾入,而出队是从队首出。

队列的数组实现

和栈一样,队列也有很多种实现方式,最基本的可以使用数组或者链表来实现。

先考虑一下使用数组来存储数据的情况。

我们用head表示队首的index,使用rear表示队尾的index。

当队尾不断插入,队首不断取数据的情况下,很有可能出现下面的情况:

上面图中,head的index已经是2了,rear已经到了数组的最后面,再往数组里面插数据应该怎么插入呢?

如果再往rear后面插入数据,head前面的两个空间就浪费了。这时候需要我们使用循环数组。

循环数组怎么实现呢?只需要把数组的最后一个节点和数组的最前面的一个节点连接即可。

有同学又要问了。数组怎么变成循环数组呢?数组又不能像链表那样前后连接。

不急,我们先考虑一个余数的概念,假如我们知道了数组的capacity,当要想数组插入数据的时候,我们还是照常的将rear+1,但是最后除以数组的capacity, 队尾变到了队首,也就间接的实现了循环数组。

看下java代码是怎么实现的:

public class ArrayQueue {

//存储数据的数组
private int[] array;
//head索引
private int head;
//real索引
private int rear;
//数组容量
private int capacity;

public ArrayQueue (int capacity){
this.capacity=capacity;
this.head=-1;
this.rear =-1;
this.array= new int[capacity];
}

public boolean isEmpty(){
return head == -1;
}

public boolean isFull(){
return (rear +1)%capacity==head;
}

public int getQueueSize(){
if(head == -1){
return 0;
}
return (rear +1-head+capacity)%capacity;
}

//从尾部入队列
public void enQueue(int data){
if(isFull()){
System.out.println("Queue is full");
}else{
//从尾部插入
rear = (rear +1)%capacity;
array[rear]= data;
//如果插入之前队列为空,将head指向real
if(head == -1 ){
head = rear;
}
}
}

//从头部取数据
public int deQueue(){
int data;
if(isEmpty()){
System.out.println("Queue is empty");
return -1;
}else{
data= array[head];
//如果只有一个元素,则重置head和real
if(head == rear){
head= -1;
rear = -1;
}else{
head = (head+1)%capacity;
}
return data;
}
}
}

大家注意我们的enQueue和deQueue中使用的方法:

rear = (rear +1)%capacity
head = (head+1)%capacity

这两个就是循环数组的实现。

队列的动态数组实现

上面的实现其实有一个问题,数组的大小是写死的,不能够动态扩容。我们再实现一个能够动态扩容的动态数组实现。

//因为是循环数组,这里不能做简单的数组拷贝
private void extendQueue(){
int newCapacity= capacity*2;
int[] newArray= new int[newCapacity];
//先全部拷贝
System.arraycopy(array,0,newArray,0,array.length);
//如果real
if(rear< head){
for(int i=0; i< head; i++){
//重置0-head的数据
newArray[i]= -1;
//拷贝到新的位置
newArray[i+capacity]=array[i];
}
//重置real的位置
rear= rear+capacity;
//重置capacity和array
capacity=newCapacity;
array=newArray;
}
}

需要注意的是,在进行数组扩展的时候,我们不能简单的进行拷贝,因为是循环数组,可能出现rear在head后面的情况。这个时候我们需要对数组进行特殊处理。

其他部分是和普通数组实现基本一样的。

队列的链表实现

除了使用数组,我们还可以使用链表来实现队列,只需要在头部删除和尾部添加即可。

看下java代码实现:

public class LinkedListQueue {
//head节点
private Node headNode;
//rear节点
private Node rearNode;

class Node {
int data;
Node next;
//Node的构造函数
Node(int d) {
data = d;
}
}

public boolean isEmpty(){
return headNode==null;
}

public void enQueue(int data){
Node newNode= new Node(data);
//将rearNode的next指向新插入的节点
if(rearNode !=null){
rearNode.next=newNode;
}
rearNode=newNode;
if(headNode == null){
headNode=newNode;
}
}

public int deQueue(){
int data;
if(isEmpty()){
System.out.println("Queue is empty");
return -1;
}else{
data=headNode.data;
headNode=headNode.next;
}
return data;
}
}

队列的时间复杂度

上面的3种实现的enQueue和deQueue方法,基本上都可以立马定位到要入队列或者出队列的位置,所以他们的时间复杂度是O(1)。

本文的代码地址:

learn-algorithm

本文已收录于 http://www.flydean.com/12-algorithm-queue/ 最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现! 欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
出战30分钟受伤离场!媒体人:武磊目前可以下地走路

出战30分钟受伤离场!媒体人:武磊目前可以下地走路

直播吧
2024-09-28 19:12:11
菲律宾刚刚对仁爱礁成功实施补给,菲海警4411船就再次偷袭仙宾礁

菲律宾刚刚对仁爱礁成功实施补给,菲海警4411船就再次偷袭仙宾礁

说天说地说实事
2024-09-28 17:47:02
陆挺呼吁保交房:不是盖了太多房子没卖掉,而是卖掉太多房子但没盖完

陆挺呼吁保交房:不是盖了太多房子没卖掉,而是卖掉太多房子但没盖完

新浪财经
2024-09-28 15:40:10
拜仁1-1勒沃库森,赛后评分:不是凯恩第一,拜仁6号排第一

拜仁1-1勒沃库森,赛后评分:不是凯恩第一,拜仁6号排第一

侧身凌空斩
2024-09-29 02:33:24
405:0!美国众议院罕见全票法案,特朗普总统发言引瞩目

405:0!美国众议院罕见全票法案,特朗普总统发言引瞩目

现代小青青慕慕
2024-09-28 08:08:47
“大饼脸”混进谍战剧,高颜值被打回原形,聂远演技再好也白搭

“大饼脸”混进谍战剧,高颜值被打回原形,聂远演技再好也白搭

十原故里
2024-09-24 22:44:05
为何世界都在穆斯林化,穆斯林为何这么厉害?关键原因有三点

为何世界都在穆斯林化,穆斯林为何这么厉害?关键原因有三点

世界就是这么精彩
2024-09-28 10:17:14
离婚仅38天!中国斯诺克名将无缝衔接再婚,迎娶神秘外籍美娇娘

离婚仅38天!中国斯诺克名将无缝衔接再婚,迎娶神秘外籍美娇娘

娱乐八卦木木子
2024-09-28 11:40:27
杨紫近照瘦了好多,比以前好看多了,也变洋气了!

杨紫近照瘦了好多,比以前好看多了,也变洋气了!

红心说娱乐
2024-09-28 13:54:24
这是有史以来第一次。央行说你可以从我这里拿钱去炒股票

这是有史以来第一次。央行说你可以从我这里拿钱去炒股票

流苏晚晴
2024-09-27 19:31:46
揭秘:女性性生活能持续到哪个年龄?

揭秘:女性性生活能持续到哪个年龄?

智见派
2024-08-13 15:44:27
没速度没身体,泰山队留洋新星徒有虚名,泽卡状态佳,亚冠留足力

没速度没身体,泰山队留洋新星徒有虚名,泽卡状态佳,亚冠留足力

替补席看球
2024-09-28 22:14:05
中午12点,何卓佳VS张本美和,孙颖莎好友收获三个好消息

中午12点,何卓佳VS张本美和,孙颖莎好友收获三个好消息

极度说球
2024-09-29 01:21:27
天塌了!多校官宣不能使用计算器!

天塌了!多校官宣不能使用计算器!

考研帮
2024-09-27 20:01:58
绝杀!阿森纳第94分钟破门

绝杀!阿森纳第94分钟破门

直播吧
2024-09-28 23:59:07
离岸人民币回落至6.98元下方

离岸人民币回落至6.98元下方

每日经济新闻
2024-09-28 07:04:08
西甲第16爆发,3-0西甲6冠王,23岁皇马旧将和24岁曼城旧将同发威

西甲第16爆发,3-0西甲6冠王,23岁皇马旧将和24岁曼城旧将同发威

侧身凌空斩
2024-09-29 03:17:07
大多数人都没意识到,我们一生其实都是由自己的心理账户所掌控的

大多数人都没意识到,我们一生其实都是由自己的心理账户所掌控的

肯定式教养
2024-09-28 22:21:58
创立弘芯的曹山,拿走政府150亿投资后逃往美国,现在怎样了

创立弘芯的曹山,拿走政府150亿投资后逃往美国,现在怎样了

老黄有话
2024-09-04 08:00:10
别跑空!宁波多个景区发布公告,国庆假期不开放!

别跑空!宁波多个景区发布公告,国庆假期不开放!

鲁中晨报
2024-09-28 21:37:10
2024-09-29 05:10:44
flydean程序那些事
flydean程序那些事
最通俗的解读,最深刻的干货!
356文章数 438关注度
往期回顾 全部

科技要闻

豆包“王炸”,字节版Sora来了,有多厉害

头条要闻

媒体:布林肯主动约王毅见面 双方的关注点有一些差异

头条要闻

媒体:布林肯主动约王毅见面 双方的关注点有一些差异

体育要闻

那个偶像是德里克-罗斯的男孩

娱乐要闻

噩耗!英国皇家影星玛吉史密斯离世

财经要闻

沪市部分股票深夜成交?回应来了!

汽车要闻

售11.99-14.69万元 深蓝2025款SL03正式上市

态度原创

时尚
教育
亲子
数码
房产

姚晨这样的大女人,穿上Chloé都变甜了!

教育要闻

不太对呀,姐姐放假只想玩一玩,没想到在家里面更累了

亲子要闻

秋季童装上新!原创卡通图案,卫衣外套都是实穿款,低至29元

数码要闻

喜马拉雅与苹果播客合作:引入数千个频道与节目内容

房产要闻

实地测评:比商品房贵,看“一线村景”!海口这个安居盘,你会买吗?

无障碍浏览 进入关怀版