二叉堆

来源:互联网 发布:caffe 前向计算 编辑:程序博客网 时间:2024/05/24 03:07

堆是一颗完全被填满的二叉树,有可能的例外是在底层,底层的元素从左到右填满。完全二叉树
二叉堆又可分为最大堆,最小堆。最小堆就是节点元素值小于等于两儿子。
完全二叉树可以用一个数组表示,a[0] 位置空出(后面有用)

对于数组任意位置i上的元素, 其左儿子在位置2i上,右儿子在位置2i+1上, 父节点在i/2上。因此不需要链。问题在最大的堆的大小需要事先估计,但是一般不成问题,可以调整大小。

// 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 );    }}
0 0