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

  

 //:ThinkingInJava/com.mindview.fundamental/MaxHeap.java
package com.mindview.fundamental;
/**
*
* @Time 2014-6-17
* @Descri MaxHeap.java 最大堆排序实现算法
* parent (i-1)/2
* left 2*i+1
* right 2*i+2
* @author pattywgm
*
*/
public class MaxHeap {
int a[];
int a_heapsize;
//接受数组
public MaxHeap(int a[]) {
this.a=a;
a_heapsize=a.length;
} //堆排序
public void heapSort(){
buildMaxHeap();
for(int i=a.length-1;i>0;i--){
//从大到小输出,实际数组顺序输出为从小到大
// System.out.print(a[0]+" ");
exchange(0, i);
a_heapsize=a_heapsize-1;
maxHeapIFY(0);//from top to bottom
}
} //创建堆
public void buildMaxHeap(){
//a[(a.length-1)/2] to a[0] is not leaf
for(int i=(a.length/2-1);i>=0;i--){
maxHeapIFY(i);
}
}
//调整堆,以使其符合最大堆性质
public void maxHeapIFY( int i) {
int aLeft=2*i+1;//leftChild
int aRight=2*i+2;//rightChild
int largest;
if(aLeft<a_heapsize && a[aLeft]>a[i])
largest=aLeft;
else
largest=i;
if(aRight<a_heapsize && a[aRight]>a[largest])
largest=aRight;
if(largest!=i){
exchange(i,largest);
//子树可能违反最大堆性质,继续调整
maxHeapIFY(largest);
} }
//exchange A[i] with A[largest]
public void exchange(int i, int largest) {
int temp=a[i];
a[i]=a[largest];
a[largest]=temp; }
} ///:~

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

 //:ThinkingInJava/com.mindview.fundamental/MaxPriorityQueue.java
package com.mindview.fundamental;
/**
*
* @Time 2014-6-17
* @Descri MaxPriorityQueue.java
* 基于最大堆,实现最大优先队列,最大优先队列应用于作业调度
* 可将作业长度作为关键字,进行比较
* @author pattywgm
*
*/
public class MaxPriorityQueue {
int task[];
MaxHeap heap;
public MaxPriorityQueue(int[] task) {
this.task=task;
heap=new MaxHeap(task);
heap.buildMaxHeap();//创建最大堆
}
//获取最大关键字
public int heapMaxiMum(){
return task[0];
}
//去掉并返回最大关键字
public int heapExtractMax(){
if(heap.a_heapsize<1){
System.out.println("Error:heap underflow");
return -1;
}
else{
int max=task[0];
task[0]=task[heap.a_heapsize-1];
heap.a_heapsize=heap.a_heapsize-1;
heap.maxHeapIFY(0);
return max;
}
}
//在堆中插入元素x
public void heapInsert(int x){
task[heap.a_heapsize]=-1;
System.out.println("insert: "+heap.a_heapsize);
heap.a_heapsize=heap.a_heapsize+1;
if(heap.a_heapsize>task.length){
System.out.println("Error:array overflow");
return;
}
else{
heapIncreaseKey(heap.a_heapsize-1,x);
}
}
//将元素x值增加到key
public void heapIncreaseKey(int i,int key){
if(task[i]>=key){
System.out.println("new key is not bigger than current key");
return;
}
else{
task[i]=key;
//parent: (i-1)/2
while(i>0 && task[(i-1)/2]<task[i]){
heap.exchange(i, (i-1)/2);
i=(i-1)/2;
}
}
} public void print(){
for(int i=0;i<heap.a_heapsize;i++){
System.out.print(task[i]+" ");
}
} } ///:~

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

java基础之:堆排序的更多相关文章

  1. Java基础复习笔记基本排序算法

    Java基础复习笔记基本排序算法 1. 排序 排序是一个历来都是很多算法家热衷的领域,到现在还有很多数学家兼计算机专家还在研究.而排序是计算机程序开发中常用的一种操作.为何需要排序呢.我们在所有的系统 ...

  2. Java基础学习经验分享

    很多人学习Java,尤其是自学的人,在学习的过程中会遇到各种各样的问题以及难点,有时候卡在一个点上可能需要很长时间,因为你在自学的过程中不知道如何去掌握和灵活运用以及该注意的点.下面我整理了新手学习可 ...

  3. 精心收集java基础106条

    Java基础 1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 一个Java源文件中可以定义多个类,但最多只能定义一个public的类,并且public ...

  4. Java基础语法(8)-数组中的常见排序算法

    title: Java基础语法(8)-数组中的常见排序算法 blog: CSDN data: Java学习路线及视频 1.基本概念 排序: 是计算机程序设计中的一项重要操作,其功能是指一个数据元素集合 ...

  5. Java基础知识(壹)

    写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...

  6. [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)

    如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html   谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...

  7. 【JAVA面试题系列一】面试题总汇--JAVA基础部分

    JAVA基础 基础部分的顺序: 基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法 线程的语法,集合的语法,io 的语法,虚拟机方面的语法 每天几道,持续更新!! 1.一个". ...

  8. 最适合作为Java基础面试题之Singleton模式

    看似只是最简单的一种设计模式,可细细挖掘,static.synchronized.volatile关键字.内部类.对象克隆.序列化.枚举类型.反射和类加载机制等基础却又不易理解透彻的Java知识纷纷呼 ...

  9. java基础练习 字符串,控制流,日历,日期等

    1,对基本控制流程的一些练习 package org.base.practice3; import org.junit.Test; /** * Created with IntelliJ IDEA. ...

随机推荐

  1. 【其它】 MathJax - 网页中显示数学公式的终极武器

    最近在学习一些数学课程.但时间一长,发现很多东西又都忘了.而且过程中的很多心得没有留下记录,觉得挺可惜的.所以决定开个博客来记录一些东西,也希望能同数学爱好者们一起学习. 但写数学博客首先得解决显示数 ...

  2. 用JS编写日历的简单思路

    提要:本文以写当前时间环境下当月的日历表为例,用最简单的方法实现JavaScript日历,旨在展示JS世界中实用为本.简单为上的解决问题的思路. Web页中的日历一般离不开表格,通常都使用表格装载指定 ...

  3. 入口点函数的19种消息,AcRxArxApp只处理16种。

    AcRx::AppMsgCode一共有19种消息. 但由IMPLEMENT_ARX_ENTRYPOINT宏实现的App类,只处理了16种消息. 缺: kSuspendMsg = 16,    kIni ...

  4. .NET微信自定义分享标题、缩略图、超链接及描述的设置方法

    前端Js引用: <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> ...

  5. IOS开发-第三方SDWebImage下载网络图片的使用

    从网络上请求图片时,没有使用第三方的话,下载会很慢,而且堵塞线程,还要自己处理多线程问题,效果还非常不明显,使用了SDWebImage这个第三方类库之后,下载图片就变的容易多了. SDWebImage ...

  6. HackerRank "TBS Problem" ~ NPC

    It is marked as a NPC problem. However from the #1 code submission (https://www.hackerrank.com/Charl ...

  7. gulp.js简单操作

    一.安装gulp 1.深入设置任务之前,需先安装gulp: $ npm install gulp -g 2.这会将gulp安装到全域环境下,让你可以存取gulp的CLI.接著,需要在本地端的专案进行安 ...

  8. 黄聪:详解 ManualResetEvent(转)

    原文:http://www.cnblogs.com/li-peng/p/3291306.html 今天详细说一下ManualResetEvent 它可以通知一个或多个正在等待的线程已发生事件,允许线程 ...

  9. .Net 一些好工具

    1.代码类 ReSharper :代码检查,代码补齐,(收费)(vs插件) MultiEditing: vs多行编译工具 VSCommand : Web Essentials : Css扩展支持,JS ...

  10. VGA逐行扫描控制器的Verilog建模

    前言:因为VGA是一种模拟图像传输数据接口,所要将数字信号用DAC转换成模拟量.本文用的一款ADI公司高精度的视频IC,实则一款高带宽的视频DAC.因为VGA时序较为简单,并且网上的VGA驱动基本大同 ...