Java实现---堆排序 Heap Sort
堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先讲解下什么是数据结构中的二叉堆。
堆的定义
n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆。
情形1:ki <= k2i 且ki <= k2i+1 (最小化堆或小顶堆)
情形2:ki >= k2i 且ki >= k2i+1 (最大化堆或大顶堆)
其中i=1,2,…,n/2向下取整;
若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。
由此,若序列{k1,k2,…,kn}是堆,则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。
堆的存储
一般用数组来表示堆,若根结点存在序号0处, i结点的父结点下标就为(i-1)/2。i结点的左右子结点下标分别为2*i+1和2*i+2。

堆排序的实现
实现堆排序需要解决两个问题:
1.如何由一个无序序列建成一个堆?
2.如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?
先考虑第二个问题,一般在输出堆顶元素之后,视为将这个元素排除,然后用表中最后一个元素填补它的位置,自上向下进行调整:首先将堆顶元素和它的左右子树的根结点进行比较,把最小的元素交换到堆顶;然后顺着被破坏的路径一路调整下去,直至叶子结点,就得到新的堆。
我们称这个自堆顶至叶子的调整过程为“筛选”。
从无序序列建立堆的过程就是一个反复“筛选”的过程。
示例代码:
package heapSort; /**
* 堆排序,采用顺序存储
* 大根堆
* @author 超超boy
*
*/
public class HeapSort2 {
int[] arr;
public static void main(String[] args) {
// TODO Auto-generated method stub
HeapSort2 heapSor = new HeapSort2();
int[] arr = {7,23,45,9,40,73,12,49}; //0下标放的是数组长度,
heapSor.arr = arr;
heapSor.heapSort(arr); for(int i=0;i<arr.length;i++)
System.out.print(".."+arr[i]);
}
void heapAdjust(int[] arr,int s,int m){
//已知arr[s...m]中记录的关键字除arr[s]之外均满足堆的定义,本函数调整arr[s]的关键字,使arr[s...m]成为一个最大堆
int rc = arr[s]; //s是最后一个非叶子节点 for(int j=2*s;j <= m;j = s*2){
if(j<m && arr[j]<arr[j+1])
j++; //j为key较大的下标
if(rc >= arr[j]) break;
arr[s] = arr[j]; //上移到父节点
s=j;
}
arr[s]=rc; //要放入的位置 } void heapSort(int[] arr){
//对数组进行建堆操作,就是从最后一个非叶结点进行筛选的过程
for(int i=(arr.length-1)/2;i > 0;i--){//因为0没有使用,所以length-1
heapAdjust(arr,i,arr.length-1);
}
System.out.println("........建堆完成............."); outputArr(1);
for(int i=arr.length-1; i>1; i--){
int temp = arr[1];
arr[1] = arr[i];
arr[i] = temp;
heapAdjust(arr,1,i-1);
}
}
void outputArr(int i){ if(i <= arr[0]){
System.out.println(arr[i]);
outputArr(i*2); //左
outputArr(i*2+1); //右
}
}
}
运行结果:
.....................
73
45
40
23
49
12
9
..7..9..12..23..40..45..49..73
堆排序分析
堆排序方法对记录数较少的文件并不值得提倡,但对n较大的文件还是很有效的。因为其运行时间主要耗费在建初始堆和调整建新堆时进行的反复“筛选”上。
堆排序在最坏的情况下,其时间复杂度也为O(nlogn)。相对于快速排序来说,这是堆排序的最大优点。此外,堆排序仅需一个记录大小的供交换用的辅助存储空间。
转发请注明出处:http://www.cnblogs.com/jycboy/p/5689728.html
Java实现---堆排序 Heap Sort的更多相关文章
- 数据结构 - 堆排序(heap sort) 具体解释 及 代码(C++)
堆排序(heap sort) 具体解释 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 堆排序包括两个步骤: 第一步: 是建立大顶堆(从大到小排 ...
- Python入门篇-数据结构堆排序Heap Sort
Python入门篇-数据结构堆排序Heap Sort 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.堆Heap 堆是一个完全二叉树 每个非叶子结点都要大于或者等于其左右孩子结点 ...
- 堆排序 Heap Sort
堆排序虽然叫heap sort,但是和内存上的那个heap并没有实际关系.算法上,堆排序一般使用数组的形式来实现,即binary heap. 我们可以将堆排序所使用的堆int[] heap视为一个完全 ...
- 算法----堆排序(heap sort)
堆排序是利用堆进行排序的高效算法,其能实现O(NlogN)的排序时间复杂度,详细算法分析能够点击堆排序算法时间复杂度分析. 算法实现: 调整堆: void sort::sink(int* a, con ...
- 堆排序Heap sort
堆排序有点小复杂,分成三块 第一块,什么是堆,什么是最大堆 第二块,怎么将堆调整为最大堆,这部分是重点 第三块,堆排序介绍 第一块,什么是堆,什么是最大堆 什么是堆 这里的堆(二叉堆),指得不是堆栈的 ...
- 小小c#算法题 - 7 - 堆排序 (Heap Sort)
在讨论堆排序之前,我们先来讨论一下另外一种排序算法——插入排序.插入排序的逻辑相当简单,先遍历一遍数组找到最小值,然后将这个最小值跟第一个元素交换.然后遍历第一个元素之后的n-1个元素,得到这n-1个 ...
- 数据结构与算法---堆排序(Heap sort)
堆排序基本介绍 1.堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序. 2.堆是具有以下性质的完全二叉树:每个 ...
- [Unity][Heap sort]用Unity动态演示堆排序的过程(How Heap Sort Works)
[Unity][Heap sort]用Unity动态演示堆排序的过程 How Heap Sort Works 最近做了一个用Unity3D动态演示堆排序过程的程序. I've made this ap ...
- 【算法】堆排序(Heap Sort)(七)
堆排序(Heap Sort) 堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法.堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父 ...
随机推荐
- Azure China (2) Azure China管理界面初探
<Windows Azure Platform 系列文章目录> 首先是Q&A时间 1.我在Azure Global拥有测试账号或者免费的MSDN订阅账号,这个账号可以在国内Azur ...
- redis学习之三配置文件redis.conf 的含义
摘自http://www.runoob.com/redis/redis-conf.html 安装redis之后的第一件事,我就开始配置密码,结果总是不生效,而我居然还没想到原因.今天突然用命令行设置了 ...
- SQL Server代理(4/12):配置数据库邮件
SQL Server代理是所有实时数据库的核心.代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的.这系列文章会通俗介绍它的很多用法. 在以前的文章里我们看到,SQL Serve ...
- 大M法(Big M Method)
前面一篇讲的单纯形方法的实现,但程序输入的必须是已经有初始基本可行解的单纯形表. 但实际问题中很少有现成的基本可行解,比如以下这个问题: min f(x) = –3x1 +x2 + x3 s.t. x ...
- Swift泛型Protocol对比C#泛型Interface
本篇纯属抬杠之作,之前我们提到了Swift的泛型Protocol使用associatedtype关键字,而不是使用<Type>语法的泛型参数.这其中有什么好处呢? 我就这个问题搜索了一些回 ...
- JS魔法堂:彻底理解0.1 + 0.2 === 0.30000000000000004的背后
Brief 一天有个朋友问我“JS中计算0.7 * 180怎么会等于125.99999999998,坑也太多了吧!”那时我猜测是二进制表示数值时发生round-off error所导致,但并不清楚具体 ...
- angularjs input上传图片前获取图片的Size
首先我们需要一个指令来追踪input的change.ngChage不适用input[file]. app.directive("fileread", [function () { ...
- Sql去重语句
海量数据(百万以上),其中有些全部字段都相同,有些部分字段相同,怎样高效去除重复? 如果要删除手机(mobilePhone),电话(officePhone),邮件(email)同时都相同的数据,以前一 ...
- 炉石传说 C# 开发笔记
最近在大连的同事强力推荐我玩 炉石传说,一个卡牌游戏.加上五一放一个很长很长的假期,为了磨练自己,决定尝试开发一个C#的炉石传说. 这件事情有人已经干过了,开发了一个网页版的炉石,但是貌似不能玩... ...
- Asp.NET——GridView绑定DataSet数据
---------------------------------------------