一、队列
队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
二、双端队列
双端队列是只既可以在表的前端进行插入和删除操作,又可以在表的后端进行插入和删除操作。
三、ArrayDeque的实现
Java中的双端队列是用数组实现的,类的全限名称是java.util.ArrayDeque,该类的声明如下:
public class ArrayDeque<E> extends AbstractCollection<E>implements Deque<E>, Cloneable, Serializable{}
该类继承了AbstractCollection类,实现了Deque、Cloneable和Serializable接口。实现Cloneable和Serializable接口的主要目的是为了实现克隆和序列化。
该类中定义了四个个成员变量
public class ArrayDeque<E> extends AbstractCollection<E>
implements Deque<E>, Cloneable, Serializable
{
private transient E[] elements;
private transient int head;
private transient int tail;
private static final int MIN_INITIAL_CAPACITY = 8;
}
其中elements是数组的首地址,head是指向队首的下标,tail是指向队尾的下一个位置的下标。MIN_INITIAL_CAPACITY 定义了在创建队列是,如果有指定长度,而且指定长度小于MIN_INITIAL_CAPACITY,则使用MIN_INITIAL_CAPACITY 作为数组的最小长度。
其构造函数有一下几种:
public ArrayDeque() {
elements = (E[]) new Object[16];
}
第一种构造函数,默认情况下,数组的长度为16。
public ArrayDeque(int numElements) {
allocateElements(numElements);
}
第二种构造函数,给定数组长度,则调用allocateElements()函数,分配数组空间。allocateElements()函数的实现如下:
private void allocateElements(int numElements) {
int initialCapacity = MIN_INITIAL_CAPACITY;
if (numElements >= initialCapacity) {
initialCapacity = numElements;
initialCapacity |= (initialCapacity >>> 1);
initialCapacity |= (initialCapacity >>> 2);
initialCapacity |= (initialCapacity >>> 4);
initialCapacity |= (initialCapacity >>> 8);
initialCapacity |= (initialCapacity >>> 16);
initialCapacity++;
if (initialCapacity < 0) // Too many elements, must back off
initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
}
elements = (E[]) new Object[initialCapacity];
}
对于一个给定长度,先判断是否小于定义的最小长度,如果小于,则使用定义的最小长度作为数组的长度。否则,找到比给定长度大的最小的2的幂数(在if里面的以为语句实现这一功能)。
public ArrayDeque(Collection<? extends E> c) {
allocateElements(c.size());
addAll(c);
}
第三种构造函数,给定一个集合,先分配空间,然后添加到集合中。
从上面的三种构造函数中,可以判断出来,数组的长度是2的幂数,定义为2的幂数个人认为有两个原因:
1.伙伴系统
操作系统分配内存的方法使用伙伴系统的话,每一块的大小都是2的幂数,如果分配的内存大小为2的幂数,可以减少内存分配的时间。
伙伴系统在百度百科中的解释:http://baike.baidu.com/view/4935190.htm
2.插入和删除的速度
对于数组,如果head的值为0,时,在队首插入元素,有一种方法是将全部元素都向后移动一位,然后将新的元素插入。这样子的话,插入和删除的速度会非常慢,特别是在元素很多的情况下。另一种方法就是在head的值为0时,在队首插入元素,可以将head的值置为(数组的长度-1)。也就是将新插入的元素放到数组的最后,以此类推。在计算插入元素位置下标的时候,数组长度是2的幂数就用处了。下面是插入元素时,计算插入位置的值的语句
head = (head - 1) & (elements.length - 1)
length-1的值为高位全为0,低位全为1,通过按位相与,可以得出应该插入元素的位置。
然后就是该类的一些方法了,有点面向对象的思想的都应该会想到,应该有头插,头删,尾插,尾删等等一些操作,在此就不一一列出了,实现起来也比较简单。关键还是要了解ArrayDeque的实现机制。
分享到:
相关推荐
- **java.util.ArrayDeque类**:提供了双端队列功能,可以作为高效的顺序队列实现。 6. **队列的应用场景** - **任务调度**:操作系统中,进程调度器使用队列来存储待执行的任务。 - **缓冲区管理**:在网络传输...
- **`ArrayDeque`**:这是一个基于数组的双端队列,提供了对两端的快速访问。它可以作为栈、队列或双向队列使用。 - **`LinkedList`**:虽然主要用作链表,但也可以用作队列,提供对列表两端的快速插入和删除操作。 ...
1. **ArrayDeque**:ArrayDeque是一个基于数组实现的双端队列,可以作为栈或队列使用。它的操作效率通常高于 LinkedList,因为它是通过数组进行操作,而不需要像 LinkedList 那样遍历链表。 2. **LinkedList**:...
此外,学习"JAVA数据结构与算法"还包括理解和实现数据结构和算法的时间复杂度与空间复杂度分析,这有助于评估代码的运行效率。通过学习和实践,开发者可以编写出更高效、更具扩展性的代码,从而在面试、项目开发或...
本主题将深入探讨Java中的五种基础数据结构:链表、队列、栈、双端队列(deque)以及堆。我们将通过分析给定的源代码文件来理解这些数据结构的实现。 首先,链表是一种线性数据结构,它不连续存储数据,而是通过...
《邓俊辉版Java数据结构源码》是学习数据结构与算法的重要参考资料,它与邓俊辉教授编写的《Java数据结构》教材相配套,旨在帮助读者深入理解数据结构的概念和实现方法。邓俊辉教授的讲解风格清晰易懂,他的源码同样...
本篇文章将深入探讨如何用Java语言来实现这种基本的数据结构。 1. **队列的基本操作** - **enqueue()**: 将元素添加到队列的尾部。这是队列的插入操作。 - **dequeue()**: 移除并返回队列的头部元素。这是队列的...
Java的`ArrayDeque`类是一种高效的双端队列实现,支持在两端进行插入和删除操作。`offer()`用于在队尾添加元素,`poll()`从队头移除并返回元素,`peek()`查看队头元素但不移除,`isEmpty()`则用于检查队列是否为空。...
在Java中实现这两种数据结构,我们可以选择使用现有的容器类,如`ArrayDeque`作为双端队列的基础,或者自定义一个类来模拟随机队列的行为。`ArrayDeque`是基于数组的双端队列实现,它提供了高效的O(1)时间复杂度的...
Java提供了ArrayDeque类实现双端队列,Queue接口则定义了基本的队列操作。 5. **哈希表**:哈希表通过哈希函数将键映射到数组位置,提供快速的查找、插入和删除操作。Java中的HashMap类是实现哈希表的典型例子,它...
ArrayDeque类是Java集合框架中的一种双端队列的实现类,具有无限的扩展、非线程安全、支持fast-fail等特征。其实现方法包括添加元素、删除元素、扩容等,都是基于循环数组的方式来完成双端队列的功能。
Java提供了`LinkedList`作为队列的实现,以及`ArrayDeque`作为高效的双端队列。 5. **树**:包括二叉树、二叉搜索树、平衡树(AVL、红黑树等)。树结构在排序、查找、关联关系表示等方面非常有用。Java标准库并未...
13. **双端队列(Deque)**:双端队列允许在两端进行插入和删除操作,`ArrayDeque`是高效的实现。 这些数据结构在解决问题时有着广泛的应用,如排序、搜索、图算法等。通过学习和实践这些代码,初学者不仅能理解...
"java数据结构.rar"这个压缩包文件包含了一份名为"数据结构与算法分析(Java版).pdf"的资源,它详细阐述了Java语言中的数据结构及其相关算法。下面我们将深入探讨Java中的主要数据结构以及它们的应用。 首先,数组是...
这些Java数据结构在实际编程中有着广泛的应用。例如: - 数组适用于存储固定大小且类型相同的元素集合,常用于基础计算和内存效率要求高的场景。 - 列表(如ArrayList和LinkedList)在需要动态调整大小和频繁增删...
- **`Queue`**:实现先进先出(FIFO)队列数据结构,主要实现有`ArrayDeque`、`LinkedList`等。 - **`Deque`**:双端队列接口,支持两端添加和删除元素。 - **`Map`**:键值对集合,主要实现有`HashMap`、`...
LinkedList可以作为队列实现,另外还有ArrayDeque类提供更高效的双端队列操作。 5. **队列的变种:优先队列**:Java的PriorityQueue类实现了优先队列,其中元素根据其自然顺序或Comparator进行排序。 6. **散列...
Java数据结构是编程基础知识的重要组成部分,对于理解和优化程序性能至关重要。在这个“最最适用的Java数据结构全集”中,你将找到一系列关于如何在Java中实现和使用各种数据结构的源代码。让我们深入探讨一下这些...
11. **队列的变种:双端队列**(Deque):支持两端插入和移除,`java.util.Deque`接口由`ArrayDeque`和`LinkedList`实现。 12. **堆**(Heap):一种特殊的树形数据结构,通常用于实现优先队列。Java的`...
3. 高级数据结构实现:如Java的`java.util.Queue`接口,提供了多种队列实现,如`ArrayDeque`(基于数组的双端队列)、`LinkedList`(链表实现)等。 队列的应用场景: 1. 打印机任务调度:新任务入队,完成的任务出...