zoukankan      html  css  js  c++  java
  • java基础之:堆排序

      最近做题目饱受打击,愈发觉得打好基础的重要性,于是乎,决心把基本的排序算法还有数组操作一一实现,目的在于
    一方面能够得到对JAVA基础的巩固,另一面在实现的过程中发现不足。
      今天所实现的堆排序(最大堆)算法,最小堆大同小异。然后基于最大堆实现最大优先队列,最大优先队列可应用于作
    业调度,比如可将作业长度作为关键字值,实现最长作业优先;或者将作业优先权值作为关键字值,实现高优先权作业优先
    执行等等。
    最大堆排序算法结构如下图:

      

     1 //:ThinkingInJava/com.mindview.fundamental/MaxHeap.java
     2 package com.mindview.fundamental;
     3 /**
     4  * 
     5  * @Time 2014-6-17
     6  * @Descri MaxHeap.java 最大堆排序实现算法
     7  *             parent (i-1)/2
     8  *             left 2*i+1
     9  *             right 2*i+2
    10  * @author pattywgm
    11  *
    12  */
    13 public class MaxHeap {
    14     int a[];
    15     int a_heapsize;
    16     //接受数组
    17     public MaxHeap(int a[]) {
    18         this.a=a;
    19         a_heapsize=a.length;
    20     }
    21     
    22     //堆排序
    23     public void heapSort(){
    24         buildMaxHeap();
    25         for(int i=a.length-1;i>0;i--){
    26             //从大到小输出,实际数组顺序输出为从小到大
    27 //            System.out.print(a[0]+"  ");
    28             exchange(0, i);
    29             a_heapsize=a_heapsize-1;
    30             maxHeapIFY(0);//from top to bottom
    31         }
    32     }
    33     
    34     //创建堆
    35     public void buildMaxHeap(){
    36         //a[(a.length-1)/2] to a[0] is not leaf
    37         for(int i=(a.length/2-1);i>=0;i--){
    38             maxHeapIFY(i);
    39         }
    40     }
    41     //调整堆,以使其符合最大堆性质
    42     public void maxHeapIFY( int i) {
    43         int aLeft=2*i+1;//leftChild
    44         int aRight=2*i+2;//rightChild
    45         int largest;
    46         if(aLeft<a_heapsize && a[aLeft]>a[i])
    47             largest=aLeft;
    48         else
    49             largest=i;
    50         if(aRight<a_heapsize && a[aRight]>a[largest])
    51             largest=aRight;
    52         if(largest!=i){
    53             exchange(i,largest);
    54             //子树可能违反最大堆性质,继续调整
    55             maxHeapIFY(largest);
    56         }
    57         
    58         
    59     }
    60     //exchange A[i] with A[largest]
    61     public void exchange(int i, int largest) {
    62         int temp=a[i];
    63         a[i]=a[largest];
    64         a[largest]=temp;
    65         
    66     }
    67 }
    68 
    69 ///:~
    View Code

      其中buildMaxHeap()实现建立最大堆,HeapSort()方法首先调用该方法建立最大堆,然后获取堆顶元素即为最大元素,
    将其与堆底最后一个元素交换后输出到数组中,此时得到新的堆大小,并通过maxHeapIFY()方法继续调整堆,以使堆能够
    满足最大堆性质。循环迭代该过程,即可实现最大堆的排序,数组中最后保存的元素顺序是从小到大的。
    最大优先队列算法结构图如下:

     1 //:ThinkingInJava/com.mindview.fundamental/MaxPriorityQueue.java
     2 package com.mindview.fundamental;
     3 /**
     4  * 
     5  * @Time 2014-6-17
     6  * @Descri MaxPriorityQueue.java
     7  *            基于最大堆,实现最大优先队列,最大优先队列应用于作业调度
     8  *           可将作业长度作为关键字,进行比较
     9  * @author pattywgm
    10  *
    11  */
    12 public class MaxPriorityQueue {
    13     int task[];
    14     MaxHeap heap;
    15     public MaxPriorityQueue(int[] task) {
    16         this.task=task;
    17         heap=new MaxHeap(task);
    18         heap.buildMaxHeap();//创建最大堆
    19     }
    20     //获取最大关键字
    21     public int heapMaxiMum(){
    22         return task[0];
    23     }
    24     //去掉并返回最大关键字
    25     public int heapExtractMax(){
    26         if(heap.a_heapsize<1){
    27             System.out.println("Error:heap underflow");
    28             return -1;
    29         }
    30         else{
    31             int max=task[0];
    32             task[0]=task[heap.a_heapsize-1];
    33             heap.a_heapsize=heap.a_heapsize-1;
    34             heap.maxHeapIFY(0);
    35             return max;
    36         }
    37     }
    38     //在堆中插入元素x
    39     public void heapInsert(int x){
    40         task[heap.a_heapsize]=-1;
    41         System.out.println("insert: "+heap.a_heapsize);
    42         heap.a_heapsize=heap.a_heapsize+1;
    43         if(heap.a_heapsize>task.length){
    44             System.out.println("Error:array overflow");
    45             return;
    46         }
    47         else{
    48             heapIncreaseKey(heap.a_heapsize-1,x);
    49         }
    50     }
    51     //将元素x值增加到key
    52     public void heapIncreaseKey(int i,int key){
    53         if(task[i]>=key){
    54             System.out.println("new key is not bigger than current key");
    55             return;
    56         }
    57         else{
    58             task[i]=key;
    59             //parent: (i-1)/2
    60             while(i>0 && task[(i-1)/2]<task[i]){
    61                 heap.exchange(i, (i-1)/2);
    62                 i=(i-1)/2;
    63             }
    64         }
    65     }
    66     
    67     public void print(){
    68         for(int i=0;i<heap.a_heapsize;i++){
    69             System.out.print(task[i]+"  ");
    70         }
    71     }
    72     
    73 }
    74 
    75 ///:~
    View Code

      初始化调用MaxHeap类的buildMaxHeap()实现建立最大堆,即初始的最大优先队列。该最大优先队列支持以下操作:
        1)heapMaxiMum():获取最大关键字值(依据最大堆性质,实际上只是获取堆顶元素)
        2)heapExtractMax():去掉并返回最大关键字值,此时应注意重新调整堆(包括堆的大小和重新排列)
        3)heapInsert(key):在现有队列中插入元素key,该操作与4)结合实现
        4) heapIncreaseKey(i,key):将队列中指定位置处的值增加到key,注意值增加后堆性质的满足与否并做出相
        应调整
      映射到作业调度的问题,可将作业优先权值作为关键字值,1)或 2)操作获取当前作业队列中具有最高优先权的作业
    进行调度, 2)操作更符合实际情况,在调度的同时更新队列;3)操作当有新的作业到来时将其插入优先权队列,并遵守
    最大优先权最先执行的原则;4)操作在作业执行过程中,可能某个在优先权队列中的作业急需被调用,而其当前优先权却
    不高,那么就需要提高其优先权,以使其能够被尽早调度。

  • 相关阅读:
    201521044091《Java程序设计》第7周学习总结
    201521044091《java程序设计》第四次总结
    201521044091 《java程序设计》第八周学习总结
    201521044091 《Java程序设计》第5周学习总结
    201521044091 《Java程序设计》第2周学习总结
    201521044091 《Java程序设计》第3周学习总结
    MySQL设置字符集CHARACTER SET
    Create My MySQL configuration by Percona
    How to use jQuery to manipulate Cookies
    How to use OpenXml to import xml data to Sql server
  • 原文地址:https://www.cnblogs.com/java-wgm/p/3793143.html
Copyright © 2011-2022 走看看