java基础之:堆排序
最近做题目饱受打击,愈发觉得打好基础的重要性,于是乎,决心把基本的排序算法还有数组操作一一实现,目的在于
一方面能够得到对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基础之:堆排序的更多相关文章
- Java基础复习笔记基本排序算法
Java基础复习笔记基本排序算法 1. 排序 排序是一个历来都是很多算法家热衷的领域,到现在还有很多数学家兼计算机专家还在研究.而排序是计算机程序开发中常用的一种操作.为何需要排序呢.我们在所有的系统 ...
- Java基础学习经验分享
很多人学习Java,尤其是自学的人,在学习的过程中会遇到各种各样的问题以及难点,有时候卡在一个点上可能需要很长时间,因为你在自学的过程中不知道如何去掌握和灵活运用以及该注意的点.下面我整理了新手学习可 ...
- 精心收集java基础106条
Java基础 1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 一个Java源文件中可以定义多个类,但最多只能定义一个public的类,并且public ...
- Java基础语法(8)-数组中的常见排序算法
title: Java基础语法(8)-数组中的常见排序算法 blog: CSDN data: Java学习路线及视频 1.基本概念 排序: 是计算机程序设计中的一项重要操作,其功能是指一个数据元素集合 ...
- Java基础知识(壹)
写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...
- [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)
如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html 谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...
- 【JAVA面试题系列一】面试题总汇--JAVA基础部分
JAVA基础 基础部分的顺序: 基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法 线程的语法,集合的语法,io 的语法,虚拟机方面的语法 每天几道,持续更新!! 1.一个". ...
- 最适合作为Java基础面试题之Singleton模式
看似只是最简单的一种设计模式,可细细挖掘,static.synchronized.volatile关键字.内部类.对象克隆.序列化.枚举类型.反射和类加载机制等基础却又不易理解透彻的Java知识纷纷呼 ...
- java基础练习 字符串,控制流,日历,日期等
1,对基本控制流程的一些练习 package org.base.practice3; import org.junit.Test; /** * Created with IntelliJ IDEA. ...
随机推荐
- Java 异步处理简单实践
Java 异步处理简单实践 http://www.cnblogs.com/fangfan/p/4047932.html 同步与异步 通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而异 ...
- angular+bootstrap+MVC 之三,分页控件初级版
今天实现一个分页控件,效果如下: 1.HTML: <!doctype html> <!--suppress ALL --> <html ng-app="appT ...
- 使用C#和.NET的原因
早在2000年6月,微软公布.NET之后不久,Ximian公司诞生了一个开源项目叫做Mono,运行在Linux环境下面的C#编译器和.NET Framework.十年后,在2011年,Ximian的创 ...
- sql创建表格 转载
http://blog.csdn.net/wuxiaokaixinguo/article/details/8293048 检查数据库中是否存在某个表,不存在则生成该表方法一:IF NOT EXISTS ...
- fgets读取文件时的注意事项
1 文本文件 a.txt 内容如下 2 c代码 FILE *fil; if (!(fil = fopen("/home/rudy/projects/paser/a.txt", &q ...
- unity3d 镜头随触屏移动
js #pragma strict //用于绑定参照物对象 var target : Transform; //缩放系数 var distance = 10.0; //左右滑动移动速度 var xSp ...
- delphi 调用c#dll
public interface iProduct { string Buy(); } [ClassInterface(ClassInterfaceType.None)] public class P ...
- JavaScript(Iframe、window.open、window.showModalDialog)父窗口与子窗口之间的操作
一.Iframe 篇 公共部分 //父对象得到子窗口的值 //ObjectID是窗口标识,ContentID是元素ID function GetValue(ObjectID,ContentID) { ...
- java 代码判断图片格式后缀名称
/** * 图片判断 */ private static String getFormatName(Object o) { try { // Create an image input stream ...
- NHibernate系列文章八:NHibernate对象一级缓存
摘要 Nhibernatea缓存非常强大,按照缓存存储在Session对象还是SessionFactory对象分为一级缓存和二级缓存. 一级缓存存在于Session对象里,也叫Session缓存,由S ...