介绍
双端队列,和前面学的队列和栈的区别在于双端队列2端都可以进行增删,其他2个都是只能一端可以增/删。
实现
链表
因为2端都需要可以操作所以我们使用双向链表
我们也需要一共头节点
所以节点设置
static class Node<E>{
E value;
Node<E> next;
Node<E> pre;
public Node(Node<E> pre,E value,Node<E> next){
this.value = value;
this.pre = pre;
this.next = next;
}
}
队列的类维护:
- 容量
- 队列元素个数
- 哨兵
哨兵初始头和尾都指向自己,value为null
添加/删除就是操作哨兵的前后就可以了如。
offerFirest向头节点添加:
- 头节点为哨兵的next
- 然后就是链表操作就可以了
这种操作应该在链表学习的时候很熟悉了,就都没写了。
其他的同理
数组
维护一共头尾指针操作数组前后就可以了。具体直接看下面java的ArrayDeque类实现就可以了。
java实现类学习
双端队列的接口Deque集成自Quene队列接口,可用于队列的计算。
实现主要有
链表实现的LinkedList,这个类的作用太多了,当然在链表里面一般在重点讲,这里就不详细说了。
LinkedList
LinkedList既然能做双端队列,那么其方法也就都实现了的。
实现大概就是上面讲的哪样子实现的
ArrayDeque
ArrayDeque是java双端队列的数组实现方式。
阵列deques没有容量限制;它们根据需要增长以支持使用。它们不是线程安全的;在没有外部同步的情况下,它们不支持多个线程的并发访问。禁止使用空元素。当用作堆栈时,这个类可能比Stack快,当用作队列时,它可能比LinkedList快。
维护的头尾指针还有数组
构造
构造上初始化容量
如果传递的集合,则拷贝
未给容量则按照16+1,双指针1需要留着用于区分为空和为满
给定容量小于1,则按1
等于int的最大值,则按照int的最大值否则则是给定值+1,1也是不存的。
tail和head是不需要初始化的因为java默认就是0
操作
-
添加头部
先让head取模减一
然后在让head位置设置值 -
新增尾部
和头部不一样的是,这里是先设置值在取模+1
- 删除
删除和新增就相反了,head是取模+,tail是取模-
其他的实现都还好理解
扩容
在新增的时候有一个grow函数,是其扩容的函数。类似
重点在框的部分
如果小于64则每次+2
如果大于64则每次加倍