借助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实现的更多相关文章

  1. Java中的队列Queue,优先级队列PriorityQueue

    队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...

  2. java中PriorityQueue优先级队列使用方法

    优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果不提供Comparator的话,优先 ...

  3. 《转》JAVA中PriorityQueue优先级队列使用方法

    该文章转自:http://blog.csdn.net/hiphopmattshi/article/details/7334487 优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最 ...

  4. 【转】java中PriorityQueue优先级队列使用方法

    优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果不提供Comparator的话,优先 ...

  5. Java Queue之PriorityQueue

    PriorityQueue位于Java util包中,观其名字前半部分的单词Priority是优先的意思,实际上这个队列就是具有“优先级”.既然具有优先级的特性,那么就得有个前后排序的“规则”.所以其 ...

  6. # Java Queue系列之PriorityQueue

    在上一篇中我用一张图来梳理了一下Java中的各种Queue之间的关系.这里介绍下PriorityQueue.PriorityQueue位于Java util包中,观其名字前半部分的单词Priority ...

  7. java 中PriorityQueue优先级队列使用方法

    1.前言 优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果想实现按照自己的意愿进行优 ...

  8. 【Java源码】集合类-优先队列PriorityQueue

    一.类继承关系 public class PriorityQueue<E> extends AbstractQueue<E> implements java.io.Serial ...

  9. Java找N个数中最小的K个数,PriorityQueue和Arrays.sort()两种实现方法

    最近看到了 java.util.PriorityQueue.刚看到还没什么感觉,今天突然发现他可以用来找N个数中最小的K个数. 假设有如下 10 个整数. 5 2 0 1 4 8 6 9 7 3 怎么 ...

随机推荐

  1. Windows Mobile入门

    转自 http://www.cnblogs.com/peterzb/archive/2009/05/12/1455256.html [准备篇]        最近安排做手机视频监控方面开发,这个对我来 ...

  2. sudo 的介绍

    http://chenfage.blog.51cto.com/8804946/1830424

  3. Android:相机适配及图片处理的一些问题

    链接:http://www.cnblogs.com/liushilin/p/6387263.html 链接:http://www.cnblogs.com/liushilin/p/5956691.htm ...

  4. 关于NOIP的运行环境

    目前(2019年2月22日)仍然是 G++ , 终端运行,命令行: g++ test.cpp -o test ,而g++ 4.8.4默认标准是: -std=gnu++ . g++到了gcc6才把默认标 ...

  5. apicloud开发笔记

    第一次用apicloud做正式项目 ,下面把做的过程中用到的代码段列出来....都是从文档里复制的代码,只是感觉官网那个文档好难找哦... 注:api.????的方法都是在APP中调用才行的,$api ...

  6. Duplicate &lt;http&gt; element detected

    1.错误描写叙述    org.springframework.beans.factory.parsing.BeanDefinitionParsingException:Configuration p ...

  7. Linux的sysctl 命令参数详解

    Linux内核通过/proc虚拟文件系统向用户导出内核信息,用户也可以通过/proc文件系统或通过sysctl命令动态配置内核.比如,如果我们想启动NAT,除了加载模块.配置防火墙外,还需要启动内核转 ...

  8. [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 ...

  9. psycopg使用

    1.使用示例 import psycopg2 # 建立数据库连接 conn = psycopg2.connect("dbname=test user=postgres") # 开启 ...

  10. js获取iframe中的元素以及在iframe中获取父级的元素(包括iframe中不存在name和id的情况)

      第一种情况:iframe中不存在name和id的方法:(通过contentWindow获取) var iframe = document.getElementsByTagName('iframe' ...