堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

根据根结点是否是最大值还是最小值和子结点的键值是否小于还是大于它的父结点可分为两种堆,如下:

  1.大顶堆:每个结点的键值都小于它的父结点;

  2.小顶堆:每个结点的键值都大于它的父节点;

堆排序基本思想:

  1.将数组排列成大顶堆(或小顶堆);

  2.把根结点和尾结点交换,然后把n-1个元素重新构成一个大顶堆(或小顶堆);

  3.重复第2步,直到最后一个元素。

流程图(为了不太麻烦,所以就减少些数据):

一,先将数组排序成大顶堆

二,把根结点和末尾结点交换

代码:

 /**
* 堆排序
*/
public class TestHeap {
//创建大顶堆
public static void maximumHeap(int k, int[] arr,int m) {
int i, j, temp;
boolean finished;
i = k;
j = 2*i+1;
temp = arr[k];
finished = false;
while((j <= m) && !finished){
//孩子结点位置小于数组长度 且 右孩子大于左孩子
if ((j < m) && (arr[j+1] > arr[j])){
j++; //把右孩子结点当作最大孩子结点
}
//如果最大的孩子结点小于其根节点
if (temp >= arr[j]){
finished = true; //结束循环
}else{
//把最大子节点赋给根结点
arr[i] = arr[j];
i = j;
//循环下一个根结点
j = 2*j+1;
}
}
arr[i] = temp;
} //交换
public static void heapsort(int[] arrays) {
int i;
//从最后一个非叶节点开始构建大顶堆
for (i = arrays.length / 2 - 1; i >= 0; i--) {
maximumHeap(i, arrays, arrays.length);
}
System.out.println("建堆后:" + Arrays.toString(arrays));
//从最小的叶子节点开始与根节点进行交换并重新构建大顶堆
for (i = arrays.length - 1; i >= 1; i--) {
int temp = arrays[i];
arrays[i] = arrays[0];
arrays[0] = temp;
maximumHeap(0, arrays,i-1);
}
System.out.println(Arrays.toString(arrays));
} public static void main(String[] args) {
int[] arrays = {49, 38, 65, 97, 176, 213, 227, 49, 78, 34, 12, 164, 11, 18, 1};
heapsort(arrays);
}
}

测试结果:

建堆后:[227, 176, 213, 97, 38, 164, 65, 49, 78, 34, 12, 49, 11, 18, 1]
[1, 11, 12, 18, 34, 38, 49, 49, 65, 78, 97, 164, 176, 213, 227]

时间复杂度:堆排序方法对记录数n较大的文件排序是很好的,但当n较小时,不提倡使用,因为初始建堆和调整建新堆时要进行反复的筛选。堆排序时间复杂度为O(nlog2n)。

堆排序只需存放一个记录的附加空间。

堆排序是一种不稳定的排序算法。

结语:堆排序是为了即要保存中间比较结果,减少后面的比较次数,又不占用大量的附加存储空间,使排序算法具有较好的性能才被Willioms和Floyd在1964年提出的。

Java八大排序之堆排序的更多相关文章

  1. Java八大排序算法

    Java八大排序算法: package sort; import java.util.ArrayList; import java.util.Arrays; import java.util.List ...

  2. 八大排序算法——堆排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 先来了解下堆的相关概念:堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆:或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆.如 ...

  3. java八大排序代码

    import java.util.ArrayList;import java.util.List; public class FastSort { public static void main(St ...

  4. 必须知道的Java八大排序算法

    冒泡排序.简单选择.直接插入.快速排序.堆排序.希尔排序.归并排序.基数排序. 将其按排序方式分类如下图所示: 1.冒泡排序: 基本思想——在要排序的一组数中,对当前还未排好序的范围内的全部数据,自上 ...

  5. Java八大排序之希尔(Shell)排序

    希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该 ...

  6. Java八大排序之插入排序

    插入排序 也可叫直接插入排序,该算法的思路是:初始可认为文件中的第1个记录已排好序,然后将第2个到第n个记录依次插入到已排序的记录组成的文件中. 步骤: 假设有一组数组为(数组下标0—n-1): ar ...

  7. Java八大排序之基数排序

    基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分 ...

  8. 八大排序算法Java

    目录(?)[-] 概述 插入排序直接插入排序Straight Insertion Sort 插入排序希尔排序Shells Sort 选择排序简单选择排序Simple Selection Sort 选择 ...

  9. 八大排序算法Java实现

    本文对常见的排序算法进行了总结. 常见排序算法如下: 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 它们都属于内部排序,也就是只考虑数据量较小仅需要使用内存的排 ...

随机推荐

  1. Linux性能优化实战学习笔记:第五十五讲

    一.上节回顾 上一节,我们一起学习了,应用程序监控的基本思路,先简单回顾一下.应用程序的监控,可以分为指标监控和日志监控两大块. 指标监控,主要是对一定时间段内的性能指标进行测量,然后再通过时间序列的 ...

  2. MySQL实战45讲学习笔记:第二十三讲

    一.本节概要 今天这篇文章,我会继续和你介绍在业务高峰期临时提升性能的方法.从文章标题“MySQL 是怎么保证数据不丢的?”,你就可以看出来,今天我和你介绍的方法,跟数据的可靠性有关. 在专栏前面文章 ...

  3. [LeetCode] 25. Reverse Nodes in k-Group 每k个一组翻转链表

    Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. k  ...

  4. linux 修改oracle的字符集

    select   userenv('language')   from   dual; 命令可以查看服务端的使用的字符集. ssh登录,切换到oracle用户 切换用户命令:su -oracle 之后 ...

  5. Laravel源码解析之model(代码)

    本篇文章给大家带来的内容是关于Laravel源码解析之model(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 前言 提前预祝猿人们国庆快乐,吃好.喝好.玩好,我会在电视上看 ...

  6. java内存简单描述

    分为四块:data segment,code segment,堆,栈. data segment :数据段,存放静态变量,字符串常量. code segment:代码段,存放代码. 栈:存放局部变量. ...

  7. java中 Math和StrictMath

    今天无意中看到java api中有StrictMath 这个工具类,发现它部分调用实现是用了Math中的实现.Math 这个类API 1.0版本就有了,StrictMath API是1.3版本才出来的 ...

  8. UWP 使用exe程序

    0  添加程序到UWP中 1  添加引用 Windows Desktop Extensions For The UWP 2 修改清单文件(在清单文件上右键查看代码) 2.1 添加xmlns引用 //P ...

  9. Window应急响应(六):NesMiner挖矿病毒

    0x00 前言 作为一个运维工程师,而非一个专业的病毒分析工程师,遇到了比较复杂的病毒怎么办?别怕,虽然对二进制不熟,但是依靠系统运维的经验,我们可以用自己的方式来解决它. 0x01 感染现象 1.向 ...

  10. Java学习:常用函数接口

    常用函数接口 什么是函数式接口? 函数式接口,@FunctionalInterface,简称FI,简单的说,FI就是指仅含有一个抽象方法的接口,以@Functionalnterface标注 注意:这里 ...