`
mixer_a
  • 浏览: 363616 次
社区版块
存档分类
最新评论

Java数据结构 -ArrayDeque 双端队列的简单分析

阅读更多

 

一、队列

队列是一种特殊的线性表,它只允许在表的前端(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的实现机制。

 

7
1
分享到:
评论
2 楼 long_yu2 2012-05-21  
1 楼 bk_lin 2012-05-20  
以前没听说过,学习了

相关推荐

    Java语言编写的数据结构-队列实现

    - **java.util.ArrayDeque类**:提供了双端队列功能,可以作为高效的顺序队列实现。 6. **队列的应用场景** - **任务调度**:操作系统中,进程调度器使用队列来存储待执行的任务。 - **缓冲区管理**:在网络传输...

    Java基础复习笔记06数据结构-队列

    - **`ArrayDeque`**:这是一个基于数组的双端队列,提供了对两端的快速访问。它可以作为栈、队列或双向队列使用。 - **`LinkedList`**:虽然主要用作链表,但也可以用作队列,提供对列表两端的快速插入和删除操作。 ...

    队列(数据结构--Java版)

    1. **ArrayDeque**:ArrayDeque是一个基于数组实现的双端队列,可以作为栈或队列使用。它的操作效率通常高于 LinkedList,因为它是通过数组进行操作,而不需要像 LinkedList 那样遍历链表。 2. **LinkedList**:...

    JAVA数据结构与算法(中英全)

    此外,学习"JAVA数据结构与算法"还包括理解和实现数据结构和算法的时间复杂度与空间复杂度分析,这有助于评估代码的运行效率。通过学习和实践,开发者可以编写出更高效、更具扩展性的代码,从而在面试、项目开发或...

    JAVA基本5种数据结构的实现。

    本主题将深入探讨Java中的五种基础数据结构:链表、队列、栈、双端队列(deque)以及堆。我们将通过分析给定的源代码文件来理解这些数据结构的实现。 首先,链表是一种线性数据结构,它不连续存储数据,而是通过...

    邓俊辉版java 数据结构源码

    《邓俊辉版Java数据结构源码》是学习数据结构与算法的重要参考资料,它与邓俊辉教授编写的《Java数据结构》教材相配套,旨在帮助读者深入理解数据结构的概念和实现方法。邓俊辉教授的讲解风格清晰易懂,他的源码同样...

    用Java实现数据结构中的队列

    本篇文章将深入探讨如何用Java语言来实现这种基本的数据结构。 1. **队列的基本操作** - **enqueue()**: 将元素添加到队列的尾部。这是队列的插入操作。 - **dequeue()**: 移除并返回队列的头部元素。这是队列的...

    java实现数据结构

    Java的`ArrayDeque`类是一种高效的双端队列实现,支持在两端进行插入和删除操作。`offer()`用于在队尾添加元素,`poll()`从队头移除并返回元素,`peek()`查看队头元素但不移除,`isEmpty()`则用于检查队列是否为空。...

    Deque-and-Randomized-Queue:算法的双端队列和随机队列的实现I

    在Java中实现这两种数据结构,我们可以选择使用现有的容器类,如`ArrayDeque`作为双端队列的基础,或者自定义一个类来模拟随机队列的行为。`ArrayDeque`是基于数组的双端队列实现,它提供了高效的O(1)时间复杂度的...

    数据结构实验及相关代码(java)

    Java提供了ArrayDeque类实现双端队列,Queue接口则定义了基本的队列操作。 5. **哈希表**:哈希表通过哈希函数将键映射到数组位置,提供快速的查找、插入和删除操作。Java中的HashMap类是实现哈希表的典型例子,它...

    Java集合ArrayDeque类实例分析

    ArrayDeque类是Java集合框架中的一种双端队列的实现类,具有无限的扩展、非线程安全、支持fast-fail等特征。其实现方法包括添加元素、删除元素、扩容等,都是基于循环数组的方式来完成双端队列的功能。

    Java数据结构学习资料源码.zip

    Java提供了`LinkedList`作为队列的实现,以及`ArrayDeque`作为高效的双端队列。 5. **树**:包括二叉树、二叉搜索树、平衡树(AVL、红黑树等)。树结构在排序、查找、关联关系表示等方面非常有用。Java标准库并未...

    java版数据结构代码

    13. **双端队列(Deque)**:双端队列允许在两端进行插入和删除操作,`ArrayDeque`是高效的实现。 这些数据结构在解决问题时有着广泛的应用,如排序、搜索、图算法等。通过学习和实践这些代码,初学者不仅能理解...

    java数据结构.rar

    "java数据结构.rar"这个压缩包文件包含了一份名为"数据结构与算法分析(Java版).pdf"的资源,它详细阐述了Java语言中的数据结构及其相关算法。下面我们将深入探讨Java中的主要数据结构以及它们的应用。 首先,数组是...

    Java数据结构:详解及使用场景.pdf

    这些Java数据结构在实际编程中有着广泛的应用。例如: - 数组适用于存储固定大小且类型相同的元素集合,常用于基础计算和内存效率要求高的场景。 - 列表(如ArrayList和LinkedList)在需要动态调整大小和频繁增删...

    java-collections-framework1016

    - **`Queue`**:实现先进先出(FIFO)队列数据结构,主要实现有`ArrayDeque`、`LinkedList`等。 - **`Deque`**:双端队列接口,支持两端添加和删除元素。 - **`Map`**:键值对集合,主要实现有`HashMap`、`...

    java 数据结构以及源码

    LinkedList可以作为队列实现,另外还有ArrayDeque类提供更高效的双端队列操作。 5. **队列的变种:优先队列**:Java的PriorityQueue类实现了优先队列,其中元素根据其自然顺序或Comparator进行排序。 6. **散列...

    最最适用的java数据结构全集

    Java数据结构是编程基础知识的重要组成部分,对于理解和优化程序性能至关重要。在这个“最最适用的Java数据结构全集”中,你将找到一系列关于如何在Java中实现和使用各种数据结构的源代码。让我们深入探讨一下这些...

    java数据结构源码

    11. **队列的变种:双端队列**(Deque):支持两端插入和移除,`java.util.Deque`接口由`ArrayDeque`和`LinkedList`实现。 12. **堆**(Heap):一种特殊的树形数据结构,通常用于实现优先队列。Java的`...

    数据结构——队列的实现

    3. 高级数据结构实现:如Java的`java.util.Queue`接口,提供了多种队列实现,如`ArrayDeque`(基于数组的双端队列)、`LinkedList`(链表实现)等。 队列的应用场景: 1. 打印机任务调度:新任务入队,完成的任务出...

Global site tag (gtag.js) - Google Analytics