优先队列(堆)的定义

(英语: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数据结构--优先队列(堆实现)的更多相关文章

  1. Java数据结构之堆和优先队列

    概述 在谈堆之前,我们先了解什么是优先队列.我们每天都在排队,银行,医院,购物都得排队.排在队首先处理事情,处理完才能从这个队伍离开,又有新的人来排在队尾.但仅仅这样就能满足我们生活需求吗,明显不能. ...

  2. java数据结构之(堆)栈

    (堆)栈概述栈是一种特殊的线性表,是操作受限的线性表栈的定义和特点•定义:限定仅在表尾进行插入或删除操作的线性表,表尾—栈顶,表头—栈底,不含元素的空表称空栈•特点:先进后出(FILO)或后进先出(L ...

  3. Java数据结构和算法(四)赫夫曼树

    Java数据结构和算法(四)赫夫曼树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 赫夫曼树又称为最优二叉树,赫夫曼树的一个 ...

  4. Java数据结构和算法(十四)——堆

    在Java数据结构和算法(五)——队列中我们介绍了优先级队列,优先级队列是一种抽象数据类型(ADT),它提供了删除最大(或最小)关键字值的数据项的方法,插入数据项的方法,优先级队列可以用有序数组来实现 ...

  5. Java数据结构和算法 - 堆

    堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...

  6. java数据结构和算法10(堆)

    这篇我们说说堆这种数据结构,其实到这里就暂时把java的数据结构告一段落,感觉说的也差不多了,各种常见的数据结构都说到了,其实还有一种数据结构是“图”,然而暂时对图没啥兴趣,等有兴趣的再说:还有排序算 ...

  7. java数据结构----堆

    1.堆:堆是一种树,由它实现的优先级队列的插入和删除的时间复杂度都是O(logn),用堆实现的优先级队列虽然和数组实现相比较删除慢了些,但插入的时间快的多了.当速度很重要且有很多插入操作时,可以选择堆 ...

  8. Java数据结构和算法 - 栈和队列

    Q: 栈.队列与数组的区别? A: 本篇主要涉及三种数据存储类型:栈.队列和优先级队列,它与数组主要有如下三个区别: A: (一)程序员工具 数组和其他的结构(栈.队列.链表.树等等)都适用于数据库应 ...

  9. Java之优先队列

    PriorityQueue属于Java Collections Framework.PriorityQueue基于优先级堆,它是Queue接口的实现.当我们需要一个Queue实现时,可以使用这种数据结 ...

随机推荐

  1. Openssl gendsa命令

    一.简介 gendsa命令能够根据DSA密钥参数生成DSA密钥 二.语法 openssl gendsa [-out filename] [-passout out] [-rand file(s)] [ ...

  2. ubuntu安装meshlab

    ubuntu安装meshlab https://github.com/nine7nine/meshlab.git

  3. zigbee之IAR环境搭建

    注册机第一个要选择: 为什么? 之前说CC2530是支持zigbee协议的无线芯片,其实它是这款硬件上有一个支持zigbee协议的无线电路,不仅有这款电路,而且还有一块cpu电路,它就是8051cpu ...

  4. 白盒测试实践项目(day6)

    胡俊辉负责JUint测试部分,了解JUint测试的方法,并对其他成员介绍JUint的使用,负责JUnit部分相关文档的编写,负责博客园博客的维护,负责小组成员的任务分类与管理. 李建文负责代码复审部分 ...

  5. scrapy爬虫事件以及数据保存为txt,json,mysql

    今天要爬取的网页是虎嗅网 我们将完成如下几个步骤: 创建一个新的Scrapy工程 定义你所需要要抽取的Item对象 编写一个spider来爬取某个网站并提取出所有的Item对象 编写一个Item Pi ...

  6. [GO]文件的读写

    首先写一个文件 package main import ( "os" "fmt" ) func WriteFile(path string) { //打开文件, ...

  7. Python基于VS2013 开发环境搭建 Hello World 10分钟搞定

    1.先下载Python 安装 Next ->安装完成 2.以前安装过VS2013 打开VS2013 文件->新建项目 (此时如果没有Python Application,请点击里面的安装插 ...

  8. UVa 12342 Tax Calculator (水题,纳税)

    今天在uva看到一个水题,分享一下. 题意:制定纳税的总额,有几个要求,如果第一个180000,不纳,下一个300000,纳10%,再一个400000,纳15%,再一个300000,纳20%,以后的纳 ...

  9. java调用linux管道信息的误区

    String cmd = "ps -ef | grep "XXX" " 使用Runtime rt = Runtime.getRuntime();类时 rt.ex ...

  10. Prolific PL2303 usb 转串口Win8 Win8.1驱动

    买了根USB转RS232串口的线,Pl2303芯片的.卖家和官方都称不支持Win8,但鄙人不信在Win7上能用在Win8/8.1就用不起来. 官方最新版的v1.9.0的驱动描述说不支持Win 8/8. ...