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 怎么 ...
随机推荐
- Windows Mobile入门
转自 http://www.cnblogs.com/peterzb/archive/2009/05/12/1455256.html [准备篇] 最近安排做手机视频监控方面开发,这个对我来 ...
- sudo 的介绍
http://chenfage.blog.51cto.com/8804946/1830424
- Android:相机适配及图片处理的一些问题
链接:http://www.cnblogs.com/liushilin/p/6387263.html 链接:http://www.cnblogs.com/liushilin/p/5956691.htm ...
- 关于NOIP的运行环境
目前(2019年2月22日)仍然是 G++ , 终端运行,命令行: g++ test.cpp -o test ,而g++ 4.8.4默认标准是: -std=gnu++ . g++到了gcc6才把默认标 ...
- apicloud开发笔记
第一次用apicloud做正式项目 ,下面把做的过程中用到的代码段列出来....都是从文档里复制的代码,只是感觉官网那个文档好难找哦... 注:api.????的方法都是在APP中调用才行的,$api ...
- Duplicate <http> element detected
1.错误描写叙述 org.springframework.beans.factory.parsing.BeanDefinitionParsingException:Configuration p ...
- Linux的sysctl 命令参数详解
Linux内核通过/proc虚拟文件系统向用户导出内核信息,用户也可以通过/proc文件系统或通过sysctl命令动态配置内核.比如,如果我们想启动NAT,除了加载模块.配置防火墙外,还需要启动内核转 ...
- [Windows Azure] Windows Azure Web Sites, Cloud Services, and VMs: When to use which?
This document provides guidance on how to make an informed decision in choosing between Windows Azur ...
- psycopg使用
1.使用示例 import psycopg2 # 建立数据库连接 conn = psycopg2.connect("dbname=test user=postgres") # 开启 ...
- js获取iframe中的元素以及在iframe中获取父级的元素(包括iframe中不存在name和id的情况)
第一种情况:iframe中不存在name和id的方法:(通过contentWindow获取) var iframe = document.getElementsByTagName('iframe' ...