「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」
简介
dequeue指的是双向队列,可以分别从队列的头部插入和获取数据,也可以从队列的尾部插入和获取数据。
本文将会介绍一下怎么创建dequeue和dequeue的一些基本操作。
双向队列的实现
和普通队列项目,双向队列可以分别在头部和尾部进行插入和删除工作,所以一个dequeue需要实现这4个方法:
- insertFront(): 从dequeue头部插入数据
- insertLast(): 从dequeue尾部插入数据
- deleteFront(): 从dequeue头部删除数据
- deleteLast(): 从dequeue尾部删除数据
同样的我们也需要一个head和一个rear来指向队列的头部和尾部节点。
也就是说实现了这四个方法的队列就是双向队列。我们不管它内部是怎么实现的。
接下来我们来直观的感受一下dequeue的插入和删除操作:
- 在头部插入
- 在尾部插入
- 在头部删除
- 在尾部删除
双向队列也可以有很多种实现方式,比如循环数组和链表。
双向队列的数组实现
因为数组本身已经有前后关系,也就是说知道head可以拿到它后面一个数据,知道rear也可以拿到它前面一个数据。
所以数组的实现中,存储head和rear的index值已经够了。
我们只需要添加向头部插入数据和向尾部删除数据的方法即可:
1 | java复制代码 |
双向队列的动态数组实现
动态数组可以动态改变数组大小,这里我们使用倍增的方式来扩展数组。
看下扩展方法怎么实现:
1 | java复制代码 //因为是循环数组,这里不能做简单的数组拷贝 |
因为是循环数组,这里不能做简单的数组拷贝,我们需要判断rear和head的位置来判断是否进入到了循环结构。
如果进入到了循环结构,我们需要重置相应的字段数据,并拷贝到新数组中。
向头部插入数据和向尾部删除数据的方法和基本队列的实现是一致的,这里就不列出来了。
双向队列的链表实现
如果使用链表来实现双向队列会有什么问题呢?
在头部插入和在尾部插入都可以快速定位到目标节点。但是我们考虑一下尾部删除的问题。
尾部删除我们需要找到尾部节点的前一个节点,将这个节点置位rear节点。这就需要我们能够通过rear节点找到它的前一个节点。
所以基本的链表已经满足不了我们的需求了。 这里我们需要使用双向链表。
1 | java复制代码public class LinkedListDeQueue { |
双向链表中的每一个节点都有next和prev两个指针。通过这两个指针,我们可以快速定位到他们的后一个节点和前一个节点。
双向链表的时间复杂度
上面的3种实现的enQueue和deQueue方法,基本上都可以立马定位到要入队列或者出队列的位置,所以他们的时间复杂度是O(1)。
本文的代码地址:
本文已收录于 www.flydean.com/13-algorith…
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
本文转载自: 掘金