一、堆排序和堆相关概念描述

  堆排序是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆的性质:即子结点的值总是小于(或者大于)它的父节点,若子结点的值总是小于它的父节点这堆叫大顶堆,子结点的值总是大于它的父节点这种堆叫小顶堆。若二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。如果完全二叉树有n个节点,那么有n/2(n为偶数)个叶子节点或(n+1)/2(n为奇数)个叶子节点。

二、基本思想

  先将数组array[0,...,n-1]构造成一个堆,即将array[0,...,n-1]看成是一颗完全二叉树的顺序存储结构。然后将堆调整为大顶堆(顺序排序),具体步骤如下,先找到堆的非叶子节点array[i](当n为偶数时(n-1)/2<=i<=n-1,当n为奇数时(n-2)/2<=i<=n-1),再找到这个非叶子节点的左右孩子节点(array[2i+1],array[2i+2]),将非叶子节点的值与左右孩子节点的值比较,如果非叶子节点的值小于左右孩子节点值的最大值,把最大孩子节点的最大值赋给非叶子节点,再继续找孩子节点的孩子节点,重复上述比较操作,直到找不到孩子节点为直,当所有非叶子节点重复上述操作完成时,那么这个堆就是大顶堆了。然后将堆顶元素与堆尾元素交换,将堆尾元素移除,将剩余元素组成的堆继续重复调整为大堆,交换堆顶堆尾元素,移除堆尾元素,直到剩余元素组成的堆只有一个元素为止。

三、实现步骤

  1. 构建初始堆,将待排序列构成一个大顶堆(或者小顶堆),升序大顶堆,降序小顶堆;
  2. 将堆顶元素与堆尾元素交换,移除堆尾元素。
  3. 重新构建大顶堆。
  4. 重复2~3,直到待排序列中只剩下一个元素(堆顶元素)。

四、案例分析

  以数组{6,5,3,1,8,7}为例如下图:

  

五、代码实现

public class JavaSort {
public static void main(String[] args) {
int a [] =new int []{6,5,3,1,8,7};
System.out.println("排序前的数组:"+Arrays.toString(a));
heapSort(a);
System.out.println("排序后的数组:"+Arrays.toString(a));
} /**
*
* @param ary 待排序列
*/
private static void heapSort(int[] ary) {
int len=ary.length;
if (len<=0) {
System.out.println("数组长度不能小于等于0");
} else if (len==1) {
} else {
int firstIndex=len-1;
if(len%2==0) {
firstIndex=len-2;//第一个非叶子节点位置,如果数组长度为偶数,非叶子节点为length-2/2,否则叶子长度为length-1/2.
}
for (int i = firstIndex / 2; i >= 0; i--) {
//从第一个非叶子结点从下至上,从右至左调整结构,把堆调整为大顶堆。
adjustHeap(ary, i, ary.length);
}
System.out.println("第一次构造的大顶堆"+Arrays.toString(ary)); //调整堆结构+交换堆顶元素与末尾元素
for (int i = ary.length - 1; i > 0; i--) {
//将堆顶元素与末尾元素进行交换
int temp = ary[i];
ary[i] = ary[0];
ary[0] = temp;
//将数组长度-1,移除堆尾元素,将堆顶元素进行调整,就可以将堆调整为大顶堆
System.out.println("要移除的堆尾元素:"+ary[i]);
System.out.println("移除堆尾元素后,堆为"+Arrays.toString(Arrays.copyOfRange(ary, 0, i)));
adjustHeap(ary, 0, i);
System.out.println("移除堆尾元素后,大顶堆堆为"+Arrays.toString(Arrays.copyOfRange(ary, 0, i))); } } } /**
* 调整完全二叉树的非叶子节点,使得它们的节点值大于左右孩子节点的值,左右孩子重复上述操作,直到找不到孩子节点。
* @param ary 要调整的数组
* @param parent 要调整的节点
* @param length 要调整的数组长度
*/
private static void adjustHeap(int[] ary, int parent, int length) {
//将temp作为父节点
int temp = ary[parent];
//左孩子
int lChild = 2 * parent + 1; while (lChild < length) {
//右孩子
int rChild = lChild + 1;
// 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点
if (rChild < length && ary[lChild] < ary[rChild]) {
lChild++;
} // 如果父结点的值已经大于孩子结点的值,则直接结束
if (temp >= ary[lChild]) {
break;
} // 把孩子结点的值赋给父结点
ary[parent] = ary[lChild]; //选取孩子结点的左孩子结点,继续向下找
parent = lChild;
lChild = 2 * lChild + 1;
}
ary[parent] = temp; } }

五、运行结果

六、运行结果

  空间复杂度:o(1)。

  时间复杂度:建堆:o(n),每次调整o(log n),故最好、最坏、平均情况下:o(n*logn)。

  稳定性:不稳定。

java方式实现堆排序的更多相关文章

  1. EBS中使用JAVA方式发送HTML格式邮件

    转自huan.gu专栏:http://blog.csdn.net/gh320/article/details/17174769 EBS中使用JAVA方式发送HTML格式邮件 一.开发工具:JDevel ...

  2. 配置RedisTemplate、JedisPoolConfig、JedisConnectionFactory+自定义序列化 (xml+java方式)+使用

    java方式配置RedisTemplate //spring注入ben //@Bean(name = "redisTemplate") public RedisTemplate i ...

  3. spring配置redis(xml+java方式)(最底层)

    条件:引用好架包 <dependency> <groupId>org.springframework.data</groupId> <artifactId&g ...

  4. Java方式配置Spring MVC

    概述 使用Java方式配置Spring MVC,以及回顾一下Spring MVC的各种用法. Spring MVC简述 关于Spring MVC的介绍网上有很多,这里就不再赘述了,只是要说一下,Spr ...

  5. SpringBoot-配置Java方式

    SpringBoot中使用Java方式配置步骤如下: 在类上加入@Configuration注解,代表作为配置类 在该类方法上加入@Bean注解,代表将方法返回的Bean加入Spring容器 在该类中 ...

  6. 算法-java代码实现堆排序

    堆排序 第7节 堆排序练习题 对于一个int数组,请编写一个堆排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3],6 [1,2 ...

  7. 使用Java方式连接HDFS

    IDEA中新建Maven工程,添加POM依赖, 在IDE的提示中, 点击 Import Changes 等待自动下载完成相关的依赖包. <?xml version="1.0" ...

  8. 跨域问题Java方式解决及Nginx方式解决【亲测可行】

    这两天和前端同事调试微信公众号项目,就遇到了跨域问题:网上相关博客也挺多的,但有很多细节没有点到,在此呢我也再次记录一下解决方式: (算是踩坑日记吧~ ~ ~)   !问题发现: 页面加载不出来,控制 ...

  9. Java方式bean的注入以及自动配置

    Java配置 Java配置的本质上,就是使用一个Java类去代替xml配置,这种配置方式在目前最主流的Spring Boot中得到了广泛的使用.1.引入相关Spring相关依赖 2.创建Java配置类 ...

随机推荐

  1. MySQL导出数据到文件中的方法

    MySQL导出数据到文件中的方法 1.导出数据到txt文件中实例:把数据表studscoreinfo中所有数据导出到指定的位置方法:select * from 表名 into outfile 指定导出 ...

  2. RocketMQ搭建全过程

    RocketMQ下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/rocketmq/4.3.0/rocketmq-all-4.3.0-bin-relea ...

  3. ztree根据参数动态控制是否显示复选框/单选框(静态JSON数据)

    本文不再更新,可能存在内容过时的情况,实时更新请访问原地址:ztree根据参数动态控制是否显示复选框/单选框(静态JSON数据): 现有全省各地区静态JSON数据,现在想通过Url参数,动态控制是否显 ...

  4. QtCreator中使用链接库

    说明 之前讨论的DLL的静态链接和动态连接都是基于 MSVC 编译器,但是 MinGW 似乎有另外一套类似但是不相同的机制.下文均在 windows 下使用 Qt Creator 中使用 MinGW ...

  5. CF-557C Arthur and Table 权值线段树

    Arthur and Table 题意 一个桌子有n个腿,每个腿都有一个高度,当且仅当最高的腿的数量大于桌子腿数量的一半时,桌子才是稳定的.特殊的是当只有一个腿时,桌子是稳定的,当有两个腿时两个腿必须 ...

  6. [hdu4714 Tree2cycle]树形DP

    题意:给一棵树,删边和加边的代价都为1,求把树变成一个圈所花的最小代价. 思路:对原树进行删边操作,直到将原树分成若干条链,然后通过在链之间添加边形成圈,由于删边和加边一一对应,且最后需要额外一条边连 ...

  7. [hdu1242]优先队列

    题意:给一个地图,'x'走一步代价为2,'.'走一步代价为1,求从s到t的最小代价.裸优先队列. #pragma comment(linker, "/STACK:10240000,10240 ...

  8. dedecms织梦建站后怎么防止被黑,加强安全漏洞措施?

    dedecms织梦建站后怎么防止被黑,加强安全漏洞措施? 很多人反映dedecms织梦网站被黑的情况,因为织梦相对来说漏洞还是挺多的,特别是新建设的站点,有些目录.文件该删的删,权限及安全都要设置,以 ...

  9. python --RecursionError: maximum recursion depth exceeded in comparison

    在学习汉娜塔的时候,遇到一个error RecursionError: maximum recursion depth exceeded in comparison 经过百度,百度的方法: 加上: i ...

  10. Python --元组与列表的差异

    · Python中的元组与列表类似,不同之处是元组的元素不能修改 · 元组使用小括号,不使用括号也可以,列表使用方括号 for example: