PriorityQueue的Java实现
借助heap数据结构实现。
以小顶heap为例(说明值越小优先级越高,如距离),代码如下:
// PriorityQueue.java
// Java Spatial Index Library
// Copyright (C) 2008 aled@users.sourceforge.net
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package buaa.act.ucar.moi; import java.io.Serializable; import gnu.trove.list.array.TFloatArrayList;
import gnu.trove.list.array.TIntArrayList; /**
* <p>
* Priority Queue that stores values as ints and priorities as floats. Uses a
* Heap to sort the priorities; the values are sorted "in step" with the
* priorities.
* </p>
* <p>
* A Heap is simply an array that is kept semi sorted; in particular if the
* elements of the array are arranged in a tree structure; ie
* </p>
*
* <pre>
* 00
* / \
* 01 02
* / \ / \
* 03 04 05 06
* /\ /\ /\ /\
* 07 08 09 10 11 12 13 14
* </pre>
* <p>
* then each parent is kept sorted with respect to it's immediate children. E.g.
* 00 < 01, 00 < 02, 02 < 05, 02 < 06
* </p>
* <p>
* This means that the array appears to be sorted, as long as we only ever look
* at element 0.
* </p>
* <p>
* Inserting new elements is much faster than if the entire array was kept
* sorted; a new element is appended to the array, and then recursively swapped
* with each parent to maintain the "parent is sorted w.r.t it's children"
* property.
* </p>
* <p>
* To return the "next" value it is necessary to remove the root element. The
* last element in the array is placed in the root of the tree, and is
* recursively swapped with one of it's children until the "parent is sorted
* w.r.t it's children" property is restored.
* </p>
* <p>
* Random access is slow (eg for deleting a particular value), and is not
* implemented here - if this functionality is required, then a heap probably
* isn't the right data structure.
* </p>
*/
public class PriorityQueue implements Serializable {
private static final long serialVersionUID = -5653506138757217673L;
public static final boolean SORT_ORDER_ASCENDING = true;
public static final boolean SORT_ORDER_DESCENDING = false; private TIntArrayList values = null;
private TFloatArrayList priorities = null;
private boolean sortOrder = SORT_ORDER_ASCENDING; private static boolean INTERNAL_CONSISTENCY_CHECKING = false; public PriorityQueue(boolean sortOrder) {
this(sortOrder, 10);
} public PriorityQueue(boolean sortOrder, int initialCapacity) {
this.sortOrder = sortOrder;
values = new TIntArrayList(initialCapacity);
priorities = new TFloatArrayList(initialCapacity);
} /**
* @param p1
* @param p2
* @return true if p1 has an earlier sort order than p2.
*/
private boolean sortsEarlierThan(float p1, float p2) {
if (sortOrder == SORT_ORDER_ASCENDING) {
return p1 < p2;
}
return p2 < p1;
} // to insert a value, append it to the arrays, then
// reheapify by promoting it to the correct place.
public void insert(int value, float priority) {
values.add(value);
priorities.add(priority); promote(values.size() - 1, value, priority);
} private void promote(int index, int value, float priority) {
// Consider the index to be a "hole"; i.e. don't swap priorities/values
// when moving up the tree, simply copy the parent into the hole and
// then consider the parent to be the hole.
// Finally, copy the value/priority into the hole.
while (index > 0) {
int parentIndex = (index - 1) / 2;
float parentPriority = priorities.get(parentIndex); if (sortsEarlierThan(parentPriority, priority)) {
break;
} // copy the parent entry into the current index.
values.set(index, values.get(parentIndex));
priorities.set(index, parentPriority);
index = parentIndex;
} values.set(index, value);
priorities.set(index, priority); if (INTERNAL_CONSISTENCY_CHECKING) {
check();
}
} public int size() {
return values.size();
} public void clear() {
values.clear();
priorities.clear();
} public void reset() {
values.reset();
priorities.reset();
} public int getValue() {
return values.get(0);
} public float getPriority() {
return priorities.get(0);
} private void demote(int index, int value, float priority) {
int childIndex = (index * 2) + 1; // left child while (childIndex < values.size()) {
float childPriority = priorities.get(childIndex); if (childIndex + 1 < values.size()) {
float rightPriority = priorities.get(childIndex + 1);
if (sortsEarlierThan(rightPriority, childPriority)) {
childPriority = rightPriority;
childIndex++; // right child
}
} if (sortsEarlierThan(childPriority, priority)) {
priorities.set(index, childPriority);
values.set(index, values.get(childIndex));
index = childIndex;
childIndex = (index * 2) + 1;
} else {
break;
}
} values.set(index, value);
priorities.set(index, priority);
} // get the value with the lowest priority
// creates a "hole" at the root of the tree.
// The algorithm swaps the hole with the appropriate child, until
// the last entry will fit correctly into the hole (ie is lower
// priority than its children)
public int pop() {
int ret = values.get(0); // record the value/priority of the last entry
int lastIndex = values.size() - 1;
int tempValue = values.get(lastIndex);
float tempPriority = priorities.get(lastIndex); values.removeAt(lastIndex);
priorities.removeAt(lastIndex); if (lastIndex > 0) {
demote(0, tempValue, tempPriority);
} if (INTERNAL_CONSISTENCY_CHECKING) {
check();
} return ret;
} public void setSortOrder(boolean sortOrder) {
if (this.sortOrder != sortOrder) {
this.sortOrder = sortOrder;
// reheapify the arrays
for (int i = (values.size() / 2) - 1; i >= 0; i--) {
demote(i, values.get(i), priorities.get(i));
}
}
if (INTERNAL_CONSISTENCY_CHECKING) {
check();
}
} private void check() {
// for each entry, check that the child entries have a lower or equal
// priority
int lastIndex = values.size() - 1; for (int i = 0; i < values.size() / 2; i++) {
float currentPriority = priorities.get(i); int leftIndex = (i * 2) + 1;
if (leftIndex <= lastIndex) {
float leftPriority = priorities.get(leftIndex);
if (sortsEarlierThan(leftPriority, currentPriority)) {
System.err.println("Internal error in PriorityQueue");
}
} int rightIndex = (i * 2) + 2;
if (rightIndex <= lastIndex) {
float rightPriority = priorities.get(rightIndex);
if (sortsEarlierThan(rightPriority, currentPriority)) {
System.err.println("Internal error in PriorityQueue");
}
}
}
}
}
PriorityQueue的Java实现的更多相关文章
- Java中的队列Queue,优先级队列PriorityQueue
队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...
- java中PriorityQueue优先级队列使用方法
优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果不提供Comparator的话,优先 ...
- 《转》JAVA中PriorityQueue优先级队列使用方法
该文章转自:http://blog.csdn.net/hiphopmattshi/article/details/7334487 优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最 ...
- 【转】java中PriorityQueue优先级队列使用方法
优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果不提供Comparator的话,优先 ...
- Java Queue之PriorityQueue
PriorityQueue位于Java util包中,观其名字前半部分的单词Priority是优先的意思,实际上这个队列就是具有“优先级”.既然具有优先级的特性,那么就得有个前后排序的“规则”.所以其 ...
- # Java Queue系列之PriorityQueue
在上一篇中我用一张图来梳理了一下Java中的各种Queue之间的关系.这里介绍下PriorityQueue.PriorityQueue位于Java util包中,观其名字前半部分的单词Priority ...
- java 中PriorityQueue优先级队列使用方法
1.前言 优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果想实现按照自己的意愿进行优 ...
- 【Java源码】集合类-优先队列PriorityQueue
一.类继承关系 public class PriorityQueue<E> extends AbstractQueue<E> implements java.io.Serial ...
- Java找N个数中最小的K个数,PriorityQueue和Arrays.sort()两种实现方法
最近看到了 java.util.PriorityQueue.刚看到还没什么感觉,今天突然发现他可以用来找N个数中最小的K个数. 假设有如下 10 个整数. 5 2 0 1 4 8 6 9 7 3 怎么 ...
随机推荐
- 学习排序算法(一):单文档方法 Pointwise
学习排序算法(一):单文档方法 Pointwise 1. 基本思想 这样的方法主要是将搜索结果的文档变为特征向量,然后将排序问题转化成了机器学习中的常规的分类问题,并且是个多类分类问题. 2. 方法流 ...
- ASP.NET MVC做的微信WEBAPP中调用微信JSSDK扫一扫
今天做一个项目,是在微信上用的,微信WEB APP,里面用到了调用手机摄像头扫一扫二维码的功能,记得以前某个项目里写有的,但是找不到之前那个项目源码了,想复制粘贴也复制不了了,只好对着微信的那个开发文 ...
- CentOS7静态IP设置
[root@localhost network-scripts]# pwd /etc/sysconfig/network-scripts [root@localhost network-scripts ...
- Newton差分插值性质证明(均差与差分的关系证明)
- Postman调用WebService,包括头验证部分
Postman调用WebService时,Body中选择Raw,最右端选择XML(txt/xml),然后把某个方法显示在页面的xml拷贝到请求框中即可,如下图: 以下是postman中的设置,
- 菜鸟学SSH(十)——Hibernate核心接口
在使用Hibernate的时候,我们通常都会用的Configuration.SessionFactory.Session.Transaction.Query和Criteria等接口.通过这些接口可以, ...
- FFmpeg(9)-解码器解码代码演示(FFmpeg调用MediaCodec实现硬解码、多线程解码、及音视频解码性能测试)
一.AVFrame 用来存放解码后的数据. [相关函数] AVFrame *frame = av_frame_alloc(); // 空间分配,分配一个空间 ...
- JVM 类加载机制详解
如下图所示,JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 加载 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lan ...
- Techniques for HA IT Management
7. Techniques That Address Multiple Availability Requirements Redundancy Hardware Redundancy Example ...
- HR必备基础能力之人性
https://www.jianshu.com/p/bbb858431c81 人力资源管理-从新手到入门(正文) 第一章 必备基础能力 第三节 人性 人力资源管理者(HR)日常工作中面对的主要对象是人 ...