本文根据《大话数据结构》一书,实现了Java版的堆排序

更多:数据结构与算法合集

基本概念

  堆排序种的堆指的是数据结构中的堆,而不是内存模型中的堆。

  :可以看成一棵完全二叉树,每个结点的值都大于等于(小于等于)其左右孩子结点的值,称为大顶堆小顶堆)。

大顶堆(左)与小顶堆(右)

  堆排序的基本思想:将带排序的序列构造成大顶堆,最大值为根结点。将根结点与最后一个元素交换,对除最大值外的剩下n-1个元素重新构造成大顶堆,可以获得次大的元素。反复执行,就可以得到一个有序序列了。

  构造大顶堆的方法

  1.首先复习完全二叉树的性质,层序遍历,当第一个元素索引从0开始时,索引为i的左孩子的索引是 (2*i+1),右孩子的索引是 (2*i+2)。

  2.设计一个函数heapAdjust(),对于一个序列(除了第一个根结点外,其余结点均满足最大堆的定义),通过这个函数可以将序列调整为正确的大顶堆。

  3.正式构造:将带排序的序列看成一棵完全二叉树的层序遍历,我们从下往上,从右往左,依次将每个非叶子结点当作根结点,使用heapAdjust()调整成大顶堆。

  具体细节的实现参阅代码,比较清楚,不再赘述。

完整Java代码

(含测试代码)

/**
*
* @Description 堆排序
*
* @author yongh
*
*/
public class HeapSort {
public void heapSort(int[] arr) {
if(arr==null || arr.length<=0)
return;
int len=arr.length;
for(int i=len/2-1;i>=0;i--) { //从最后一个父结点开始构建最大堆
heapAdjust(arr,i,len-1);
}
for(int i=len-1;i>=0;i--) {
int temp=arr[0];
arr[0]=arr[i];
arr[i]=temp;
heapAdjust(arr, 0, i-1);
}
} /*
* 功能:调整堆为最大堆
* [i……j]中,除了i之外,部分子树都满足最大堆定义
*/
private void heapAdjust(int[] arr, int start, int end) {
int temp=arr[start];
int child=2*start+1;
while(child<=end) {
if(child+1<=end && arr[child+1]>arr[child]) //记得child+1<=end的判断
child++; //较大的孩子
if(arr[child]<=temp)
break;
arr[start]=arr[child];
start=child;
child=child*2+1;
}
arr[start]=temp;
} // =========测试代码=======
public void test1() {
int[] a = null;
heapSort(a);
System.out.println(Arrays.toString(a));
} public void test2() {
int[] a = {};
heapSort(a);
System.out.println(Arrays.toString(a));
} public void test3() {
int[] a = { 1 };
heapSort(a);
System.out.println(Arrays.toString(a));
} public void test4() {
int[] a = { 3, 3, 3, 3, 3 };
heapSort(a);
System.out.println(Arrays.toString(a));
} public void test5() {
int[] a = { -3, 6, 3, 1, 3, 7, 5, 6, 2 };
heapSort(a);
System.out.println(Arrays.toString(a));
} public static void main(String[] args) {
HeapSort demo = new HeapSort();
demo.test1();
demo.test2();
demo.test3();
demo.test4();
demo.test5();
}
}

  

null
[]
[]
[, , , , ]
[-, , , , , , , , ]

HeapSort

复杂度分析

  构建堆的时间复杂度为O(n);每次调整堆的时间为O(logn),共要调整n-1次,所以重建堆的时间复杂度为O(nlogn)。

  因此总体来说,堆排序的复杂度为O(nlogn)。不过由于记录的比较和交换是跳跃式进行的,因此堆排序是不稳定的排序方法。

更多:数据结构与算法合集

【Java】 大话数据结构(16) 排序算法(3) (堆排序)的更多相关文章

  1. 【Java】 大话数据结构(14) 排序算法(1) (冒泡排序及其优化)

    本文根据<大话数据结构>一书,实现了Java版的冒泡排序. 更多:数据结构与算法合集 基本概念 基本思想:将相邻的元素两两比较,根据大小关系交换位置,直到完成排序. 对n个数组成的无序数列 ...

  2. 【Java】 大话数据结构(15) 排序算法(2) (快速排序及其优化)

    本文根据<大话数据结构>一书,实现了Java版的快速排序. 更多:数据结构与算法合集 基本概念 基本思想:在每轮排序中,选取一个基准元素,其他元素中比基准元素小的排到数列的一边,大的排到数 ...

  3. 【Java】 大话数据结构(17) 排序算法(4) (归并排序)

    本文根据<大话数据结构>一书,实现了Java版的归并排序. 更多:数据结构与算法合集 基本概念 归并排序:将n个记录的序列看出n个有序的子序列,每个子序列长度为1,然后不断两两排序归并,直 ...

  4. 【Java】 大话数据结构(18) 排序算法(5) (直接插入排序)

    本文根据<大话数据结构>一书,实现了Java版的直接插入排序. 更多:数据结构与算法合集 基本概念 直接插入排序思路:类似扑克牌的排序过程,从左到右依次遍历,如果遇到一个数小于前一个数,则 ...

  5. Java常见排序算法之堆排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  6. 【Java】 大话数据结构(11) 查找算法(2)(二叉排序树/二叉搜索树)

    本文根据<大话数据结构>一书,实现了Java版的二叉排序树/二叉搜索树. 二叉排序树介绍 在上篇博客中,顺序表的插入和删除效率还可以,但查找效率很低:而有序线性表中,可以使用折半.插值.斐 ...

  7. Java中的数据结构及排序算法

    (明天补充) 主要是3种接口:List Set Map List:ArrayList,LinkedList:顺序表ArrayList,链表LinkedList,堆栈和队列可以使用LinkedList模 ...

  8. Java实现常见的排序算法

    一.排序算法 常见的排序算法主要分为下面几类: 选择排序 堆排序 冒泡排序 快速排序 插入排序 希尔排序 归并排序 桶式排序 基数排序 本文主要介绍选择排序.堆排序.冒泡排序.快速排序和归并排序的原理 ...

  9. Java 的八种排序算法

    Java 的八种排序算法 这个世界,需要遗忘的太多. 背景:工作三年,算法一问三不知. 一.八种排序算法 直接插入排序.希尔排序.简单选择排序.堆排序.冒泡排序.快速排序.归并排序和基数排序. 二.算 ...

随机推荐

  1. 【转】I²C总线上拉电阻阻值如何选择?

    I2C总线为何需要上拉电阻? I2C(Inter-Intergrated Circuit)总线是微电子通信控制领域中常用的一种总线标准,具有接线少,控制方式简单,通信速率高等优点. I2C总线的内部结 ...

  2. 【CF580C】Kefa and Park

    题目大意:给定一棵 N 个节点的有根树(其中根节点始终为 1 号节点),点有点权,点权只有 1 和 0 两种,求从根节点到叶子节点的路径中,有多少条路径满足:路径上最大连续点权为 1 的节点个数不超过 ...

  3. Java后台面试 常见问题

    Java后台面试 常见问题   从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米.百度.阿里.京东.新浪.CVTE.乐视家的研发岗offer.我找的是java后台开发,把常见的问题分享 ...

  4. jQuery EasyUI API 中文文档 - 消息框(Messager)

    http://www.cnblogs.com/Philoo/archive/2011/11/15/jeasyui_api_messager.html Messager  消息框 博客园 风流涕淌 (p ...

  5. Redis的持久化数据

    Redis支持两种持久化:RDB和AOF模式 一.名词解释: RDB:持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot).AOF:持久化记录服务器执行的 ...

  6. Docker 镜像加速器

      Docker 镜像加速器 我们使用Docker的第一步,应该是获取一个官方的镜像,例如mysql.wordpress,基于这些基础镜像我们可以开发自己个性化的应用.我们可以使用Docker命令行工 ...

  7. html js点击按钮滚动跳转定位到页面指定位置(DIV)的方法代码

    一:通过html锚点实现滚动定位到页面指定位置(DIV):    如果我们要点击实现跳转的地方是一个html锚点,也就是点击一个A标签超链接实现跳转,可以把A标签的href属性直接指向跳转指定位置的d ...

  8. MySql数据库资料收集

    1.下载MySQL历史版本 https://downloads.mysql.com/archives/community/ https://downloads.mysql.com/archives/i ...

  9. ASP.NET MVC学习笔记-----Filter(1)

    Filter类型 接口 MVC的默认实现 Description Authorization IAuthorizationFilter AuthorizeAttribute 最先执行,在其他类型的fi ...

  10. Zookeeper笔记之命令行操作

    $ZOOKEEPER_HOME/bin下的zkCli.sh进入命令行界面,使用help可查看支持的所有命令: 一.节点相关操作 create [-s] [-e] path data acl creat ...