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. ...
随机推荐
- C#后台程序重启IIS,发邮件通知
应用场景:IIS网站挂掉,系统自动重启IIS,通知相关联系人: 主要代码: 监控类 public class monitoringiis { EmailSend send = new EmailSen ...
- SpringMVC学习系列(1) 之 初识SpringMVC
1.前言: 与SpringMVC的结识源于个人之前想做一个微信公众账号的管理平台玩玩,既然要做就需要考虑平台的选择问题.由于我的朋友只有一台运行了Linux系统的虚拟主机,且上面还运行有他自己的一些论 ...
- CDN的实现原理
在描述CDN的实现原理,让我们先看传统的未加缓存服务的访问过程,以便了解CDN缓存访问方式与未加缓存访问方式的差别: 用户提交域名→浏览器对域名进行解释→得到目的主机的IP地址→根据IP地址访问发出请 ...
- X5的UI部分和传统Web页面开发的差异
http://doc.wex5.com/different-with-std-web-ui/#1 X5的UI部分和传统Web页面开发的差异 WeX5是跨端移动开发框架,BeX5是基于WeX5的企业快速 ...
- ios crash 日志分析
以下内容来自网络 https://coderwall.com/p/ezdcmg/symbolicating-an-ios-crash-log-without-the-original-dsym-fil ...
- 升级NC6.3
2014-04-23 江苏建工&用友公司会谈提纲 1,合同规定江苏建工用友NC在实施成功之后三年免服务费(2010年增补了资金管理,如果以2010年作为软件最终实施完成,那么2010-2013 ...
- css3立体旋转
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- android StringBuffer类的使用
参考 http://www.cnblogs.com/springcsc/archive/2009/12/03/1616330.html StringBuffer类和String一样,也用来代表字符串, ...
- python的中文编码问题
下文转自 http://blog.csdn.net/mayflowers/article/details/1568852 1. 在Python中使用中文 在Python中有两种默认的字符 ...
- 【转】Samba配置文件详解
一. 客户命令: 1. smbclient smbclient 命令用来存取远程 samba 服务器上的资源,它的界面到目前为止还是文本方式的,命令形式和 ftp 类似. smbclient 命令的语 ...