最近做题目饱受打击,愈发觉得打好基础的重要性,于是乎,决心把基本的排序算法还有数组操作一一实现,目的在于
一方面能够得到对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. JSON.parse()的正确用法

    昨天晚上在项目中使用JSON.parse()来将字符串格式的数据转换成json,结果悲剧了,总感觉方法没有用错,可是就是报错!想了好久,最后发现原来是json字符串格式不标准! 如:var a = “ ...

  2. knockout 学习实例6 attr

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  3. 使用Script Component源处理不规则平面文件

    微软 BI 系列随笔 - SSIS 2012 高级应用 - Script Component处理不规则平面文件 场景介绍 在使用SSIS从平面文件导入源数据时,最常遇到的是以下两种情况: 导入规则的平 ...

  4. python---字符编码

    获取系统默认字符编码 在Python代码中,普通字符串的编码方式与程序源文件编码方式一致的,而很多IDE在默认情况下,将程序源文件按照系统默认字符编码来保存的. 下面给出用Python获取系统默认编码 ...

  5. JVM参数(一)JVM类型以及编译器模式

    现在的JVM运行Java程序(和其它的兼容性语言)时在高效性和稳定性方面做的非常出色.自适应内存管理.垃圾收集.及时编译.动态类加载.锁优化——这里仅仅列举了某些场景下会发生的神奇的事情,但他们几乎不 ...

  6. [转]遍历windows服务

    原文:http://www.codeproject.com/Articles/1573/About-Windows-Services #include <windows.h> #inclu ...

  7. input自动获取焦点

    <!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>te ...

  8. oracle中的查询语句(关于出库入库信息表,明细表,把捆包箱表,单位信息表的集中查询)

    --查出所有现金中心的单位IDwith AllUnitas(select t.ORGANIZATIONID orgid,t.parentidfrom CDMS_ORGANIZATION t where ...

  9. lintcode-【简单题】链表求和

    题目: 你有两个用链表代表的整数,其中每个节点包含一个数字.数字存储按照在原来整数中相反的顺序,使得第一个数字位于链表的开头.写出一个函数将两个整数相加,用链表形式返回和. 样例: 给出两个链表 3- ...

  10. 使用Supervisor管理Celery进程。

    讲过一篇celery的,但是celery启动后并不是daemon的,在生产环境中这肯定是不可以的,那怎么办呢? 这就需要使用supervisor进行进程管理了,下面详细介绍. 一. superviso ...