- 浏览: 29171 次
- 性别:
- 来自: 湖南
最新评论
-
shuizhaosi888:
哎,,惭愧啊!竟然是个女人写的!那,学习了,谢谢分享
java数据结构-利用Heap(堆)实现PriorityQueue(优先队列) -
云初静:
贾懂凯 写道大学生活还是很自由快乐的,我现在工作了,有些时间久 ...
每次只活一天 -
贾懂凯:
大学生活还是很自由快乐的,我现在工作了,有些时间久不属于自己了 ...
每次只活一天 -
luliangy:
完全木有办法体会!~
每次只活一天 -
云初静:
tale1990 写道
每次只活一天
(一)、首先介绍下优先队列的性质(选自 JDK API)
优先队列是一个基于优先级堆的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。优先级队列不允许使用 null 元素。依靠自然顺序的优先级队列还不允许插入不可比较的对象(这样做可能导致 ClassCastException)。
此队列的头 是按指定排序方式确定的最小 元素。如果多个元素都是最小值,则头是其中一个元素——选择方法是任意的。队列获取操作 poll、remove、peek 和 element 访问处于队列头的元素。
优先级队列是无界的,但是有一个内部容量,控制着用于存储队列元素的数组大小。它通常至少等于队列的大小。随着不断向优先级队列添加元素,其容量会自动增加。无需指定容量增加策略的细节。
此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选 方法。方法 iterator() 中提供的迭代器不 保证以任何特定的顺序遍历优先级队列中的元素。如果需要按顺序遍历,请考虑使用 Arrays.sort(pq.toArray())。
(二)、优先队列中的二叉堆的实现
从(一)可得知,优先队列是至少允许插入和删除最小者这两个操作的数据结构。
其中,对于优先队列的实现,二叉堆是很常见的。
堆是一棵被完全填满的二叉树,可能例外是底层,底层上的元素从左到右依次填入。
而且如果使用数组表示二叉堆,那么对于数组上的任意位置i上的元素,其左儿子的位置是2i,右儿子在左儿子后的单元(2i +1)中,他的父亲则在位置[i/2]上。
堆的性质,在堆中,对于每一个节点X,X的父亲中的关键字小于或者等于X中的关键字,根节点除外。其中根节点是堆中关键字最小的元素。所以二叉堆的最小元可以在根处找到。
上滤策略为,现在空闲位置创建一个空穴,如果X可以放在空穴中而不破坏堆排序,那么插入完成,否则,把空穴的父节点上的元素移入空穴中,这样,空穴就朝着根的方向上行进一步,直到可以插入为止。
附上完全二叉树的一些性质:
如将一棵有n个结点的完全二叉树自顶向下,同一层自左向右连续给结点编号0, 1, 2, …, n-1,则有以下关系:
1、若i = 0, 则 i 无双亲.
2、若i > 0, 则 i 的双亲为:(i -1)/2.?
3、若2*i+1 < n, 则 i 的左子女为 2*i+1,若2*i+2 < n, 则 i 的右子女为2*i+2.
4、若结点编号i为偶数,且i!=0,则左兄弟结点i-1.
5、若结点编号i为奇数,且i!=n-1,则右兄弟结点为i+1.
6、结点i 所在层次为:log2(i+1)+1
优先队列是用的堆排序法,算法主要运用在于插入和删除:
下面的代码为二叉堆的实现
三)、源码解析
1.构造函数的创建
2.主要方法的实现(举几个例子,仅供分析。就不一一分析了。)
我的个娘啊,真是翻译不完了,暂告一阶段……=
参考资料:
1.JDK API
2.http://blog.csdn.net/a352193394/article/details/7210435
3.http://www.cxyclub.cn/n/12556/
优先队列是一个基于优先级堆的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。优先级队列不允许使用 null 元素。依靠自然顺序的优先级队列还不允许插入不可比较的对象(这样做可能导致 ClassCastException)。
此队列的头 是按指定排序方式确定的最小 元素。如果多个元素都是最小值,则头是其中一个元素——选择方法是任意的。队列获取操作 poll、remove、peek 和 element 访问处于队列头的元素。
优先级队列是无界的,但是有一个内部容量,控制着用于存储队列元素的数组大小。它通常至少等于队列的大小。随着不断向优先级队列添加元素,其容量会自动增加。无需指定容量增加策略的细节。
此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选 方法。方法 iterator() 中提供的迭代器不 保证以任何特定的顺序遍历优先级队列中的元素。如果需要按顺序遍历,请考虑使用 Arrays.sort(pq.toArray())。
(二)、优先队列中的二叉堆的实现
从(一)可得知,优先队列是至少允许插入和删除最小者这两个操作的数据结构。
其中,对于优先队列的实现,二叉堆是很常见的。
堆是一棵被完全填满的二叉树,可能例外是底层,底层上的元素从左到右依次填入。
而且如果使用数组表示二叉堆,那么对于数组上的任意位置i上的元素,其左儿子的位置是2i,右儿子在左儿子后的单元(2i +1)中,他的父亲则在位置[i/2]上。
堆的性质,在堆中,对于每一个节点X,X的父亲中的关键字小于或者等于X中的关键字,根节点除外。其中根节点是堆中关键字最小的元素。所以二叉堆的最小元可以在根处找到。
上滤策略为,现在空闲位置创建一个空穴,如果X可以放在空穴中而不破坏堆排序,那么插入完成,否则,把空穴的父节点上的元素移入空穴中,这样,空穴就朝着根的方向上行进一步,直到可以插入为止。
附上完全二叉树的一些性质:
如将一棵有n个结点的完全二叉树自顶向下,同一层自左向右连续给结点编号0, 1, 2, …, n-1,则有以下关系:
1、若i = 0, 则 i 无双亲.
2、若i > 0, 则 i 的双亲为:(i -1)/2.?
3、若2*i+1 < n, 则 i 的左子女为 2*i+1,若2*i+2 < n, 则 i 的右子女为2*i+2.
4、若结点编号i为偶数,且i!=0,则左兄弟结点i-1.
5、若结点编号i为奇数,且i!=n-1,则右兄弟结点为i+1.
6、结点i 所在层次为:log2(i+1)+1
优先队列是用的堆排序法,算法主要运用在于插入和删除:
下面的代码为二叉堆的实现
1. package com.bird.six; 2. 3. /** 4. * @category 二叉堆的实现 5. * @author Bird 6. * 7. */ 8. public class BinaryHeap { 9. 10. private static final int DEAFAULT_CAPACITY = 100; 11. private int currentSize;//堆中的元素个数 12. private Compare[] array;//存储堆中的元素使用数组存储方式 13. 14. public BinaryHeap(){ 15. this(DEAFAULT_CAPACITY); 16. } 17. 18. public BinaryHeap(int capacity){ 19. currentSize = 0; 20. array = new Compare[capacity+1]; 21. 22. } 23. 24. public boolean isEmpty(){ 25. return currentSize == 0; 26. } 27. 28. public boolean isFull(){ 29. return currentSize == array.length-1; 30. } 31. 32. public void makeEmpty(){ 33. currentSize = 0; 34. } 35. 36. /** 37. * 插入使用“上移”法 38. * @param x 39. */ 40. public void insert(Compare x){ 41. if(isFull()) 42. throw new RuntimeException("溢出"); 43. 44. int hole = ++currentSize; 45. for(; hole >1 && x.compareTo(array[hole/2]) < 0; hole /= 2) 46. array[hole] = array[hole/2]; 47. array[hole] = x; 48. } 49. 50. /** 51. * 使用下溢法进行删除操作 52. * @return 53. */ 54. public Compare deleteMin(){ 55. if(isEmpty()) 56. return null; 57. 58. Compare minItem = array[1]; 59. array[1] = array[currentSize--]; 60. percolateDown(1); 61. 62. return minItem; 63. } 64. 65. private void percolateDown(int hole){ 66. int child = 0; 67. Compare tmp = array[hole]; 68. 69. for(; hole * 2 <= currentSize; hole = child){ 70. child = hole * 2; 71. if(child != currentSize && array[child+1].compareTo(array[child])<0) 72. child++; 73. if(array[child].compareTo(tmp)<0) 74. array[hole] = array[child]; 75. else 76. break; 77. } 78. array[hole] = tmp; 79. } 80. } 81. 82. class Compare implements Comparable<Object>{ 83. 84. public int compareTo(Object o) { 85. return ((Integer)this.compareTo(o)); 86. } 87. 88. }
三)、源码解析
1.构造函数的创建
/** * Priority queue represented as a balanced binary heap: the two * children of queue[n] are queue[2*n+1] and queue[2*(n+1)]. The * priority queue is ordered by comparator, or by the elements' * natural ordering, if comparator is null: For each node n in the * heap and each descendant d of n, n <= d. The element with the * lowest value is in queue[0], assuming the queue is nonempty. * 优先级队列代表着一个平衡的二叉堆:队列[n]的两个孩子分别是队列[2*n+1]和队列[2*(n+1)]。 *先级队列的元素根据构造队列时提供的 Comparator 进行排序,或者按照其自然顺序进行排序: *如果比较器为空,则堆中的每一个结点n和它的的子节点d,有n<=d。 *如果队列不为空的话,则最小值元素是队列[0]。 */ private transient Object[] queue; /** * The number of elements in the priority queue. * 优先队列中的元素个数 */ private int size = 0; /** * The comparator, or null if priority queue uses elements' * natural ordering. * 优先队列的比较器,如果优先队列按自然排序,则为空 */ private final Comparator<? super E> comparator; /** * The number of times this priority queue has been * <i>structurally modified</i>. See AbstractList for gory details. * 该优先队列结构改变的次数,要获取更多细节,请看AbstractList。 */ private transient int modCount = 0; /** * Creates a {@code PriorityQueue} with the default initial * capacity (11) that orders its elements according to their * {@linkplain Comparable natural ordering}. * 使用默认的初始容量(11)创建一个 PriorityQueue,并根据其自然顺序对元素进行排序。 */ public PriorityQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } /** * Creates a {@code PriorityQueue} with the specified initial * capacity that orders its elements according to their * {@linkplain Comparable natural ordering}. ** 使用指定的初始容量创建一个 优先队列,并根据其自然顺序对元素进行排序 * @param initialCapacity the initial capacity for this priority queue * 初始化的容量 * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 * 如果容量小于1,则跑出异常IllegalArgumentException */ public PriorityQueue(int initialCapacity) { this(initialCapacity, null); } /** * Creates a {@code PriorityQueue} with the specified initial capacity * that orders its elements according to the specified comparator. *使用指定的初始容量创建一个 PriorityQueue,并根据指定的比较器对元素进行排序。 * @param initialCapacity the initial capacity for this priority queue * 初始化的容量 * @param comparator the comparator that will be used to order this * priority queue. If {@code null}, the {@linkplain Comparable * natural ordering} of the elements will be used. * 用于对此优先级队列进行排序的比较器。如果该参数为 null,则将使用元素的自然顺序 * @throws IllegalArgumentException if {@code initialCapacity} is * less than 1 * 如果容量小于1,则抛出异常IllegalArgumentException */ public PriorityQueue(int initialCapacity, Comparator<? super E> comparator) { // Note: This restriction of at least one is not actually needed, // but continues for 1.5 compatibility if (initialCapacity < 1) throw new IllegalArgumentException(); this.queue = new Object[initialCapacity]; this.comparator = comparator; } /** * Creates a {@code PriorityQueue} containing the elements in the * specified collection. If the specified collection is an instance of * a {@link SortedSet} or is another {@code PriorityQueue}, this * priority queue will be ordered according to the same ordering. * Otherwise, this priority queue will be ordered according to the * {@linkplain Comparable natural ordering} of its elements. *创建包含指定 collection 中元素的 PriorityQueue。如果指定的 collection 是 SortedSet 的一个实例 *或者是另一个 PriorityQueue,那么此优先级队列将根据相同顺序进行排序。否则,此优先级队列 *将根据元素的自然顺序进行排序。 * @param c the collection whose elements are to be placed * into this priority queue * 其元素要置于此优先级队列中 * @throws ClassCastException if elements of the specified collection * cannot be compared to one another according to the priority * queue's ordering * ClassCastException -如果根据 c 的顺序无法比较 c 中的各个元素 * @throws NullPointerException if the specified collection or any * of its elements are null * NullPointerException-如果指定 collection 或任何元素为 null */ public PriorityQueue(Collection<? extends E> c) { initFromCollection(c); if (c instanceof SortedSet) comparator = (Comparator<? super E>) ((SortedSet<? extends E>)c).comparator(); else if (c instanceof PriorityQueue) comparator = (Comparator<? super E>) ((PriorityQueue<? extends E>)c).comparator(); else { comparator = null; heapify(); } } /** * Creates a {@code PriorityQueue} containing the elements in the * specified priority queue. This priority queue will be * ordered according to the same ordering as the given priority * queue. *创建包含指定优先级队列元素的 PriorityQueue。此优先级队列将根据与给定优先级队列 *相同的顺序进行排序。 * into this priority queue * 有序 set,其元素将置于此优先级队列中 * @throws ClassCastException if elements of {@code c} cannot be * compared to one another according to {@code c}'s * ordering * ClassCastException -如果根据 c 的顺序无法比较 c 中的各个元素 * @throws NullPointerException if the specified priority queue or any * of its elements are null * NullPointerException-如果指定优先级队列或任何元素为 null */ public PriorityQueue(PriorityQueue<? extends E> c) { comparator = (Comparator<? super E>)c.comparator(); initFromCollection(c); } /** * Creates a {@code PriorityQueue} containing the elements in the * specified sorted set. This priority queue will be ordered * according to the same ordering as the given sorted set. *创建包含指定有序 set 元素的 PriorityQueue。此优先级队列将根据与给定有序 set 相同的顺序进行排序。 参数: * @param c the sorted set whose elements are to be placed * into this priority queue * 有序 set,其元素将置于此优先级队列中 * @throws ClassCastException if elements of the specified sorted * set cannot be compared to one another according to the * sorted set's ordering * ClassCastException - 如果根据有序 set 的顺序无法比较该有序 set 中的各个元素 * @throws NullPointerException if the specified sorted set or any * of its elements are null * NullPointerException - 如果指定有序 set 或任何元素为 null */ public PriorityQueue(SortedSet<? extends E> c) { comparator = (Comparator<? super E>)c.comparator(); initFromCollection(c); }
2.主要方法的实现(举几个例子,仅供分析。就不一一分析了。)
/** *将指定的元素插入此优先级队列。 / public boolean offer(E e) { //如果加入的元素为空,则抛出异常 if (e == null) throw new NullPointerException(); modCount++; int i = size; //如果要插入的坐标大于队列长度,队列长度加1 if (i >= queue.length) grow(i + 1); size = i + 1; //插入元素 if (i == 0) queue[0] = e; else siftUp(i, e); return true; } //获取并移除此队列的头,如果此队列为空,则返回 null。 public E poll() { if (size == 0) return null; int s = --size; modCount++; E result = (E) queue[0]; E x = (E) queue[s]; queue[s] = null; if (s != 0) siftDown(0, x); return result; } // 从此队列中移除指定元素的单个实例(如果存在)。 private E removeAt(int i) { assert i >= 0 && i < size; modCount++; int s = --size; if (s == i) // removed last element(移除最后一个元素) queue[i] = null; else { E moved = (E) queue[s]; queue[s] = null; siftDown(i, moved); if (queue[i] == moved) { siftUp(i, moved); if (queue[i] != moved) return moved; } } return null; }……
我的个娘啊,真是翻译不完了,暂告一阶段……=
参考资料:
1.JDK API
2.http://blog.csdn.net/a352193394/article/details/7210435
3.http://www.cxyclub.cn/n/12556/
发表评论
-
java设计模式之结构型模式——装饰模式((Decorator))
2012-03-10 22:43 1077一、装饰模式的定义: 装饰模式是在不必改变原类文件和使用继承的 ... -
java设计模式之创建型模式——原型模式(prototype)
2012-03-10 22:16 3290一、原型模式的定义: 用原型实例指定创建对象的种类,并且通过拷 ... -
java设计模式之创建型模式——单态模式(Singleton Pattern)
2012-03-10 21:49 1504(根据收集的各个资料整理而得~) 一、单态模式的定义 Sin ... -
OOP的7大原则(收集整理)
2012-02-25 00:31 14241. 开闭原则(the Open Closed Princip ... -
哦,总结 !( 通信阶段前期总结)
2012-01-14 20:16 1341看了下上一次写的的总结,还是11年10月份的…… 一直 ... -
人人五子棋==
2011-11-15 16:35 0“听龙哥的话,别让他受伤……” 写总结再也不能贴代码了。是件多 ... -
画板_初始_监听_颜色选择
2011-10-23 16:00 1601初始画图板的创建: 1.创建一个队列接口ListInterfa ... -
队列的优化_arraycopy_泛型_等比num
2011-10-22 15:44 1297队列的优化有三: 1.利用arraycopy(Object s ...
相关推荐
在Java中,我们可以利用堆(Heap)来实现一个简单的优先队列。堆是一种二叉树形数据结构,其每个父节点的值都大于或等于其子节点的值,这样的结构被称为最大堆。 在给定的文件中,我们有两个文件:PriorityQueue....
在实际编程中,Java提供了一个内置的`PriorityQueue`类,它基于堆实现,提供了插入、删除和查找最大/最小元素的高效操作。虽然这个内置类通常更为方便,但理解堆的底层工作原理对于优化算法和解决复杂问题至关重要。...
1. **二叉堆实现**:最常见的优先队列实现是基于二叉堆的数据结构。二叉堆是一种特殊的完全二叉树,分为最大堆和最小堆。在最大堆中,每个节点的值都大于或等于其子节点的值,因此根节点是堆中最大的元素;在最小堆...
例如,堆(Heap)是优先队列的一种实现,Java的PriorityQueue类就是基于堆实现的,适用于最高优先级任务的处理。散列表(HashMap)提供了快速的键值对查找,它的内部机制是通过哈希函数将键映射到桶中,实现O(1)的...
优先队列(Priority Queue)是数据结构中的一种特殊队列,它的主要特点是元素的出队顺序不是按照“先进先出”(FIFO)的原则,而是根据每个元素的优先级来决定。这种数据结构广泛应用于各种算法和系统设计中,如事件...
- Java的`PriorityQueue`类实现了`Queue`接口,它底层就是用二叉堆实现的。这个类不支持并集操作,但提供了`offer()`(插入)、`poll()`(删除并返回最小/最大元素)、`peek()`(查看但不移除最小/最大元素)等方法...
在Java中,优先级队列是通过`java.util.PriorityQueue`类来实现的,它基于一个二叉堆(Binary Heap)的数据结构。本文将深入探讨优先级队列的概念、实现方式以及如何在实际编程中使用。 首先,理解二叉堆是理解...
Java堆和优先队列是数据结构中两个重要的概念,在Java编程中经常被使用。在本文中,我们将详细介绍Java堆和优先队列的定义、实现和应用。 一、堆(Heap) 堆是一种特殊的二叉树,它能够实现优先队列的功能。堆的...
9. **堆(Heap)**:Java.util.PriorityQueue类实现了一个最小堆,可以用于优先级队列的操作。 10. **散列表(Hashing)**:散列函数用于将数据映射到固定大小的桶中,Java中的HashMap和HashSet都利用了散列技术来...
在Java编程语言中,优先队列(PriorityQueue)和堆(Heap)是两种重要的数据结构,它们在处理具有优先级的元素时非常有用。本文将深入探讨这些概念,并结合题目"POJ 2442"来理解它们的应用。 首先,优先队列是一种...
除了PriorityQueue,Java的`java.util.heap`包还提供了`java.util.TreeSet`和`java.util.HashMap`等类,它们内部也利用了堆的原理,如红黑树,实现了高效的查找、插入和删除操作。 掌握堆的原理和使用方法对Java...
9. **堆**:堆是一种特殊的树形数据结构,满足堆属性(最大堆或最小堆),常用于优先队列。Java的PriorityQueue和Heap类都涉及到堆的实现。 10. **排序算法**:Java中实现的排序算法有冒泡排序、选择排序、插入排序...
在Java中,优先队列的实现通常基于二叉堆(Binary Heap)这一数据结构。 二叉堆是一种完全二叉树,分为最大堆和最小堆。最大堆保证每个父节点的值都大于或等于其子节点的值,而最小堆则相反,父节点的值小于或等于...
- **堆(Heap)**:用于实现优先队列,Java的`PriorityQueue`就是基于二叉堆实现的。 2. **算法**: - **排序算法**:包括冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序、希尔排序等。 - **查找...
Java数据结构是编程基础知识的重要组成部分,对于初学者来说,理解并掌握这些概念是至关重要的。在Java中,数据结构是用来组织、存储和处理数据的特定方式。这些结构可以帮助我们更有效地执行算法,优化程序性能。...
Java的PriorityQueue类实现了优先队列,基于堆实现,可以快速找到最大或最小元素。 6. 集合(Collection):集合是Java中用于存储对象的容器,包括ArrayList、HashSet、LinkedList等。它们提供了添加、删除、查找等...
堆是一种特殊的树形数据结构,通常用作优先队列。Java的PriorityQueue类实现了堆。 ```java PriorityQueue<Integer> heap = new PriorityQueue(); heap.offer(3); // 添加元素 int minElement = heap.poll(); // ...