• 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;    //数组表示堆中元素
     1 public BinaryHeap(int capacity) {//初始化堆数组
     2         currentSize=0;
     3         array=(T[])new Comparable[capacity+1];
     4 }
     5 public BinaryHeap(T[] items) {
     6         currentSize=items.length;
     7         array=(T[])new Comparable[(currentSize+2)*11/10];
     8         
     9         int i=1;
    10         for(T item:items)
    11             array[i++]=item;//堆数组赋值
    12         buildHeap();
    13 }
    private void buildHeap() {
        for(int i=currentSize/2;i>0;i--)//逐层下滤
            percolateDown(i);
    }

    注意!用数组实现堆时,元素的下标是从1开始,不是从0开始。原因是因为当插入的元素是比堆顶还小的元素时,我们不需要对堆做任何操作即可把堆冒出。

    元素插入

     1 public void insert(T x) {
     2         if(currentSize==array.length-1)
     3             enlargeArray(array.length*2+1);//堆扩容
     4         int hole=++currentSize;    //空穴表示的数组下标
     5         /*
     6          * hole/2是当前空穴的父节点的数组下标,如果x比父节点的元素小,则父节点元素下沉,空穴上冒
     7          * */
     8         for(array[0]=x;x.compareTo(array[hole/2])<0;hole/=2)
     9             array[hole]=array[hole/2];    //元素交换
    10         array[hole]=x;
    11 }

     

    删除最小元

     删除最小元基本的思想是将最小元置为空穴,再将堆的最后一个元素放入其中,则此时的堆是不合法的,我们需要做的就是将此时的堆顶元素下沉到合适的位置。

    1 public T deleteMin() throws Exception {
    2         if(isEmpty())
    3             throw new Exception();
    4         T minItem=findMin();//获取最小元
    5         array[1]=array[currentSize--];//取出最后一个元素
    6         percolateDown(1);//元素下滤
    7         return minItem;
    8 }
     1 private void percolateDown(int hole) {//下滤元素
     2         int child;
     3         T tmp=array[hole];
     4         for(;hole*2<=currentSize;hole=child) {
     5             child=hole*2;//孩子节点的下标
     6             if(child!=currentSize&&
     7                     array[child+1].compareTo(array[child])<0)//找出较小的孩子节点
     8                 child++;
     9             if(array[child].compareTo(tmp)<0)//逐层下滤
    10                 array[hole]=array[child];//元素替换
    11             else
    12                 break;
    13         }
    14         array[hole]=tmp;
    15 }

     

    全部代码实现(数据结构与算法分析中的demo)

      1 // BinaryHeap class
      2 //
      3 // CONSTRUCTION: with optional capacity (that defaults to 100)
      4 //               or an array containing initial items
      5 //
      6 // ******************PUBLIC OPERATIONS*********************
      7 // void insert( x )       --> Insert x
      8 // Comparable deleteMin( )--> Return and remove smallest item
      9 // Comparable findMin( )  --> Return smallest item
     10 // boolean isEmpty( )     --> Return true if empty; else false
     11 // void makeEmpty( )      --> Remove all items
     12 // ******************ERRORS********************************
     13 // Throws UnderflowException as appropriate
     14 
     15 /**
     16  * Implements a binary heap.
     17  * Note that all "matching" is based on the compareTo method.
     18  * @author Mark Allen Weiss
     19  */
     20 public class BinaryHeap<AnyType extends Comparable<? super AnyType>>
     21 {
     22     /**
     23      * Construct the binary heap.
     24      */
     25     public BinaryHeap( )
     26     {
     27         this( DEFAULT_CAPACITY );
     28     }
     29 
     30     /**
     31      * Construct the binary heap.
     32      * @param capacity the capacity of the binary heap.
     33      */
     34     public BinaryHeap( int capacity )
     35     {
     36         currentSize = 0;
     37         array = (AnyType[]) new Comparable[ capacity + 1 ];
     38     }
     39     
     40     /**
     41      * Construct the binary heap given an array of items.
     42      */
     43     public BinaryHeap( AnyType [ ] items )
     44     {
     45             currentSize = items.length;
     46             array = (AnyType[]) new Comparable[ ( currentSize + 2 ) * 11 / 10 ];
     47 
     48             int i = 1;
     49             for( AnyType item : items )
     50                 array[ i++ ] = item;
     51             buildHeap( );
     52     }
     53 
     54     /**
     55      * Insert into the priority queue, maintaining heap order.
     56      * Duplicates are allowed.
     57      * @param x the item to insert.
     58      */
     59     public void insert( AnyType x )
     60     {
     61         if( currentSize == array.length - 1 )
     62             enlargeArray( array.length * 2 + 1 );
     63 
     64             // Percolate up
     65         int hole = ++currentSize;
     66         for( array[ 0 ] = x; x.compareTo( array[ hole / 2 ] ) < 0; hole /= 2 )
     67             array[ hole ] = array[ hole / 2 ];
     68         array[ hole ] = x;
     69     }
     70 
     71 
     72     private void enlargeArray( int newSize )
     73     {
     74             AnyType [] old = array;
     75             array = (AnyType []) new Comparable[ newSize ];
     76             for( int i = 0; i < old.length; i++ )
     77                 array[ i ] = old[ i ];        
     78     }
     79     
     80     /**
     81      * Find the smallest item in the priority queue.
     82      * @return the smallest item, or throw an UnderflowException if empty.
     83      */
     84     public AnyType findMin( )
     85     {
     86         if( isEmpty( ) )
     87             throw new UnderflowException( );
     88         return array[ 1 ];
     89     }
     90 
     91     /**
     92      * Remove the smallest item from the priority queue.
     93      * @return the smallest item, or throw an UnderflowException if empty.
     94      */
     95     public AnyType deleteMin( )
     96     {
     97         if( isEmpty( ) )
     98             throw new UnderflowException( );
     99 
    100         AnyType minItem = findMin( );
    101         array[ 1 ] = array[ currentSize-- ];
    102         percolateDown( 1 );
    103 
    104         return minItem;
    105     }
    106 
    107     /**
    108      * Establish heap order property from an arbitrary
    109      * arrangement of items. Runs in linear time.
    110      */
    111     private void buildHeap( )
    112     {
    113         for( int i = currentSize / 2; i > 0; i-- )
    114             percolateDown( i );
    115     }
    116 
    117     /**
    118      * Test if the priority queue is logically empty.
    119      * @return true if empty, false otherwise.
    120      */
    121     public boolean isEmpty( )
    122     {
    123         return currentSize == 0;
    124     }
    125 
    126     /**
    127      * Make the priority queue logically empty.
    128      */
    129     public void makeEmpty( )
    130     {
    131         currentSize = 0;
    132     }
    133 
    134     private static final int DEFAULT_CAPACITY = 10;
    135 
    136     private int currentSize;      // Number of elements in heap
    137     private AnyType [ ] array; // The heap array
    138 
    139     /**
    140      * Internal method to percolate down in the heap.
    141      * @param hole the index at which the percolate begins.
    142      */
    143     private void percolateDown( int hole )
    144     {
    145         int child;
    146         AnyType tmp = array[ hole ];
    147 
    148         for( ; hole * 2 <= currentSize; hole = child )
    149         {
    150             child = hole * 2;
    151             if( child != currentSize &&
    152                     array[ child + 1 ].compareTo( array[ child ] ) < 0 )
    153                 child++;
    154             if( array[ child ].compareTo( tmp ) < 0 )
    155                 array[ hole ] = array[ child ];
    156             else
    157                 break;
    158         }
    159         array[ hole ] = tmp;
    160     }
    161 
    162         // Test program
    163     public static void main( String [ ] args )
    164     {
    165         int numItems = 10000;
    166         BinaryHeap<Integer> h = new BinaryHeap<>( );
    167         int i = 37;
    168 
    169         for( i = 37; i != 0; i = ( i + 37 ) % numItems )
    170             h.insert( i );
    171         for( i = 1; i < numItems; i++ )
    172             if( h.deleteMin( ) != i )
    173                 System.out.println( "Oops! " + i );
    174     }
    175 }
    View Code

  • 相关阅读:
    常用正则表达大全
    Vue 中Bus使用
    js 获取图片url的Blob值并预览
    npm install 插件 --save与 --save -dev的区别
    layui 事件监听触发
    微信小程序之回到顶部的两种方式
    HTML 命名规范!
    SpringMvc 集成支付宝沙盒测试
    Linux 的 tomcat 自起服务
    Linux 安装 tomcat8 详细步骤
  • 原文地址:https://www.cnblogs.com/vi3nty/p/8001242.html
Copyright © 2020-2023  润新知