JAVA数据结构--优先队列(堆实现)
优先队列(堆)的定义
堆(英语:Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。在队列中,调度程序反复提取队列中第一个作业并运行,因为实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权。堆即为解决此类问题设计的一种数据结构。
我个人比较通俗的理解就是比如我们平常下载视频看,我们打算下载两部视频,一部2G,一部只有200M。优先队列的思想就是先下载那部体积较小的视频,这样也比较合理,可以下完200M后看的同时再下2G的视频。

堆是一颗被完全填满的二叉树,唯一可能的例外是在最底层。所以堆具有两个性质——堆序性和结构性。一个高为h的完全二叉树有2h或2h-1个节点,并且堆中每一个节点X的父亲的值小于或等于X中的关键字,所以堆的最小值总可以在根中找到。
堆的构造实现
private static final int DEFAULT_CAPACITY=10;//定义堆的大小
private int currentSize;//当前实际堆的大小
private T [] array; //数组表示堆中元素
public BinaryHeap(int capacity) {//初始化堆数组
currentSize=0;
array=(T[])new Comparable[capacity+1];
}
public BinaryHeap(T[] items) {
currentSize=items.length;
array=(T[])new Comparable[(currentSize+2)*11/10];
int i=1;
for(T item:items)
array[i++]=item;//堆数组赋值
buildHeap();
}
private void buildHeap() {
for(int i=currentSize/2;i>0;i--)//逐层下滤
percolateDown(i);
}
注意!用数组实现堆时,元素的下标是从1开始,不是从0开始。原因是因为当插入的元素是比堆顶还小的元素时,我们不需要对堆做任何操作即可把堆冒出。
元素插入
public void insert(T x) {
if(currentSize==array.length-1)
enlargeArray(array.length*2+1);//堆扩容
int hole=++currentSize; //空穴表示的数组下标
/*
* hole/2是当前空穴的父节点的数组下标,如果x比父节点的元素小,则父节点元素下沉,空穴上冒
* */
for(array[0]=x;x.compareTo(array[hole/2])<0;hole/=2)
array[hole]=array[hole/2]; //元素交换
array[hole]=x;
}


删除最小元
删除最小元基本的思想是将最小元置为空穴,再将堆的最后一个元素放入其中,则此时的堆是不合法的,我们需要做的就是将此时的堆顶元素下沉到合适的位置。
public T deleteMin() throws Exception {
if(isEmpty())
throw new Exception();
T minItem=findMin();//获取最小元
array[1]=array[currentSize--];//取出最后一个元素
percolateDown(1);//元素下滤
return minItem;
}
private void percolateDown(int hole) {//下滤元素
int child;
T tmp=array[hole];
for(;hole*2<=currentSize;hole=child) {
child=hole*2;//孩子节点的下标
if(child!=currentSize&&
array[child+1].compareTo(array[child])<0)//找出较小的孩子节点
child++;
if(array[child].compareTo(tmp)<0)//逐层下滤
array[hole]=array[child];//元素替换
else
break;
}
array[hole]=tmp;
}

全部代码实现(数据结构与算法分析中的demo)
// BinaryHeap class
//
// CONSTRUCTION: with optional capacity (that defaults to 100)
// or an array containing initial items
//
// ******************PUBLIC OPERATIONS*********************
// void insert( x ) --> Insert x
// Comparable deleteMin( )--> Return and remove smallest item
// Comparable findMin( ) --> Return smallest item
// boolean isEmpty( ) --> Return true if empty; else false
// void makeEmpty( ) --> Remove all items
// ******************ERRORS********************************
// Throws UnderflowException as appropriate /**
* Implements a binary heap.
* Note that all "matching" is based on the compareTo method.
* @author Mark Allen Weiss
*/
public class BinaryHeap<AnyType extends Comparable<? super AnyType>>
{
/**
* Construct the binary heap.
*/
public BinaryHeap( )
{
this( DEFAULT_CAPACITY );
} /**
* Construct the binary heap.
* @param capacity the capacity of the binary heap.
*/
public BinaryHeap( int capacity )
{
currentSize = 0;
array = (AnyType[]) new Comparable[ capacity + 1 ];
} /**
* Construct the binary heap given an array of items.
*/
public BinaryHeap( AnyType [ ] items )
{
currentSize = items.length;
array = (AnyType[]) new Comparable[ ( currentSize + 2 ) * 11 / 10 ]; int i = 1;
for( AnyType item : items )
array[ i++ ] = item;
buildHeap( );
} /**
* Insert into the priority queue, maintaining heap order.
* Duplicates are allowed.
* @param x the item to insert.
*/
public void insert( AnyType x )
{
if( currentSize == array.length - 1 )
enlargeArray( array.length * 2 + 1 ); // Percolate up
int hole = ++currentSize;
for( array[ 0 ] = x; x.compareTo( array[ hole / 2 ] ) < 0; hole /= 2 )
array[ hole ] = array[ hole / 2 ];
array[ hole ] = x;
} private void enlargeArray( int newSize )
{
AnyType [] old = array;
array = (AnyType []) new Comparable[ newSize ];
for( int i = 0; i < old.length; i++ )
array[ i ] = old[ i ];
} /**
* Find the smallest item in the priority queue.
* @return the smallest item, or throw an UnderflowException if empty.
*/
public AnyType findMin( )
{
if( isEmpty( ) )
throw new UnderflowException( );
return array[ 1 ];
} /**
* Remove the smallest item from the priority queue.
* @return the smallest item, or throw an UnderflowException if empty.
*/
public AnyType deleteMin( )
{
if( isEmpty( ) )
throw new UnderflowException( ); AnyType minItem = findMin( );
array[ 1 ] = array[ currentSize-- ];
percolateDown( 1 ); return minItem;
} /**
* Establish heap order property from an arbitrary
* arrangement of items. Runs in linear time.
*/
private void buildHeap( )
{
for( int i = currentSize / 2; i > 0; i-- )
percolateDown( i );
} /**
* Test if the priority queue is logically empty.
* @return true if empty, false otherwise.
*/
public boolean isEmpty( )
{
return currentSize == 0;
} /**
* Make the priority queue logically empty.
*/
public void makeEmpty( )
{
currentSize = 0;
} private static final int DEFAULT_CAPACITY = 10; private int currentSize; // Number of elements in heap
private AnyType [ ] array; // The heap array /**
* Internal method to percolate down in the heap.
* @param hole the index at which the percolate begins.
*/
private void percolateDown( int hole )
{
int child;
AnyType tmp = array[ hole ]; for( ; hole * 2 <= currentSize; hole = child )
{
child = hole * 2;
if( child != currentSize &&
array[ child + 1 ].compareTo( array[ child ] ) < 0 )
child++;
if( array[ child ].compareTo( tmp ) < 0 )
array[ hole ] = array[ child ];
else
break;
}
array[ hole ] = tmp;
} // Test program
public static void main( String [ ] args )
{
int numItems = 10000;
BinaryHeap<Integer> h = new BinaryHeap<>( );
int i = 37; for( i = 37; i != 0; i = ( i + 37 ) % numItems )
h.insert( i );
for( i = 1; i < numItems; i++ )
if( h.deleteMin( ) != i )
System.out.println( "Oops! " + i );
}
}
JAVA数据结构--优先队列(堆实现)的更多相关文章
- Java数据结构之堆和优先队列
概述 在谈堆之前,我们先了解什么是优先队列.我们每天都在排队,银行,医院,购物都得排队.排在队首先处理事情,处理完才能从这个队伍离开,又有新的人来排在队尾.但仅仅这样就能满足我们生活需求吗,明显不能. ...
- java数据结构之(堆)栈
(堆)栈概述栈是一种特殊的线性表,是操作受限的线性表栈的定义和特点•定义:限定仅在表尾进行插入或删除操作的线性表,表尾—栈顶,表头—栈底,不含元素的空表称空栈•特点:先进后出(FILO)或后进先出(L ...
- Java数据结构和算法(四)赫夫曼树
Java数据结构和算法(四)赫夫曼树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 赫夫曼树又称为最优二叉树,赫夫曼树的一个 ...
- Java数据结构和算法(十四)——堆
在Java数据结构和算法(五)——队列中我们介绍了优先级队列,优先级队列是一种抽象数据类型(ADT),它提供了删除最大(或最小)关键字值的数据项的方法,插入数据项的方法,优先级队列可以用有序数组来实现 ...
- Java数据结构和算法 - 堆
堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...
- java数据结构和算法10(堆)
这篇我们说说堆这种数据结构,其实到这里就暂时把java的数据结构告一段落,感觉说的也差不多了,各种常见的数据结构都说到了,其实还有一种数据结构是“图”,然而暂时对图没啥兴趣,等有兴趣的再说:还有排序算 ...
- java数据结构----堆
1.堆:堆是一种树,由它实现的优先级队列的插入和删除的时间复杂度都是O(logn),用堆实现的优先级队列虽然和数组实现相比较删除慢了些,但插入的时间快的多了.当速度很重要且有很多插入操作时,可以选择堆 ...
- Java数据结构和算法 - 栈和队列
Q: 栈.队列与数组的区别? A: 本篇主要涉及三种数据存储类型:栈.队列和优先级队列,它与数组主要有如下三个区别: A: (一)程序员工具 数组和其他的结构(栈.队列.链表.树等等)都适用于数据库应 ...
- Java之优先队列
PriorityQueue属于Java Collections Framework.PriorityQueue基于优先级堆,它是Queue接口的实现.当我们需要一个Queue实现时,可以使用这种数据结 ...
随机推荐
- Luogu 4726 【模板】多项式指数函数
补补补…… 这个题的解法让我认识到了泰勒展开的美妙之处. 泰勒展开 泰勒展开就是用一个多项式型的函数去逼近一个难以准确描述的函数. 有公式 $$f(x)\approx g(x) = g(x_0) + ...
- [BAT] 通过批处理删除7天前的报告,并删除当前目录下的空文件夹
set reportPath=D:\AutomationReport cd /d %reportPath% forfiles /p %reportPath% /s /m *.xml /d -7 /c ...
- redhad系统配置daocloud加速器
一.注册daocloud账户网址:http://www.daocloud.io/ 配置加速器需要在daocloud上注册一个用户.注册之后,登陆进去可以看到[加速器]选项. 点击加速器选项之后,就可以 ...
- Android动态加载--JVM 类加载机制
动态加载,本质上是通过JVM类加载机制将插件模块加载到宿主apk中,并通过android的相关运行机制,实现插件apk的运行.因此熟悉JVM类加载的机制非常重要. 类加载机制:虚拟机把描述类的数据从C ...
- es学习-索引别名
别名不能重复,也不能喝索引名称重复.(一个索引可以创建多个别名) 语法: 添加一个别名: url:POST http://192.168.0.108:9200/_aliases/ 参数: { &quo ...
- 团体程序设计天梯赛L2-013 红色警报 2017-03-23 22:08 55人阅读 评论(0) 收藏
L2-013. 红色警报 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 战争中保持各个城市间的连通性非常重要.本题要求你编写一 ...
- 洛谷 P2596 [ZJOI2006]书架 (splay)
题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本.由于这些 ...
- ArrayList动态数组System.Collections命名空间下
using System.Collections; namespace myspace { class myclass { ArrayList myList=new ArrayList(); } }
- Web应用与Spring MVC锁session
http是无连接的,所以服务器上并不会为每个用户开辟一个线程,因为没有用户这个说法,但是服务器端是有session的,为了防止一个用户同时有多个请求在处理,spring mvc在处理请求时把sessi ...
- 2、ASP .NETCore 2.0之视图
一.Razor基础 声明:Razor不是编程语言,是服务器端标记语言.Razor是一种允许开发者在网页中嵌入服务器端代码的标记语法(主要是针对VB和C#). 1.C#中Razor基本语法 (1).Ra ...