本文根据《大话数据结构》一书,实现了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. BZOJ 2242 [SDOI2011]计算器 | BSGS

    insert的时候忘了取模了-- #include <cstdio> #include <cmath> #include <cstring> #include &l ...

  2. 【贪心策略】渡河(river)

    “假舟楫者,非能水也,而绝江河.”这句话说的是,借助渡船的人,不是会游水,却能横渡江河. 会游水的人反而不一定能顺利地横渡江河.由于江面风浪很大,他们必须潜泳渡河.这就必须用到氧气瓶.氧气瓶当然是出题 ...

  3. POJ 3259 Wormholes(最短路径,求负环)

    POJ 3259 Wormholes(最短路径,求负环) Description While exploring his many farms, Farmer John has discovered ...

  4. [Java] I/O底层原理之二:网络IO及网络编程

    首先我们来看一下当访问一个域名时它的过程 查找 DNS 首先,浏览器检查缓存中有没有 浏览器缓存中没有,则查找操作系统中有没有配置这个对应关系 如果操作系统中也没有,则去 DNS 查找,即发送DNS报 ...

  5. spring cloud微服务架构 服务提供者和服务消费者

    服务提供者和服务消费者 下面这张表格,简单描述了服务提供者/消费者是什么:   | 名词 | 概念 | | ----- | ----------------------- | | 服务提供者 | 服务 ...

  6. Spark记录-源码编译spark2.2.0(结合Hive on Spark/Hive on MR2/Spark on Yarn)

    #spark2.2.0源码编译 #组件:mvn-3.3.9 jdk-1.8 #wget http://mirror.bit.edu.cn/apache/spark/spark-2.2.0/spark- ...

  7. 用代码块在new对象时set属性

    看到这样一种用法,很方便 request.setRequestHead(new RequestHeadType() {{ setRequestor("Online"); setRe ...

  8. rstful登陆认证并检查session是否过期

    一:restful用户视图 #!/usr/bin/env python # -*- coding:UTF-8 -*- # Author:Leslie-x from users import model ...

  9. [Alg] 尺取法

    尺取法是在线性结构中进行搜寻满足某一条件的区间的方法. 该方法保存两个索引--首索引begin.尾索引end.判断 [begin, end] 区间是否满足条件. 移动 [begin, end] 区间的 ...

  10. mysql数据库的快捷键

    mysql数据库快捷键 ctrl+q 打开查询窗口 ctrl+/ 注释sql语句 ctrl+shift +/ 解除注释 ctrl+r 运行查询窗口的sql语句 ctrl+shift+r 只运行选中的s ...