java 数据结构之堆排序(HeapSort)详解及实例

yizhihongxing

Java 数据结构之堆排序(HeapSort)详解及实例

什么是堆排序

堆排序是一种树形选择排序,它的特点是不需要建立临时数组存放已排序的元素,而是直接在原数组上进行排序,因此空间复杂度比较小,时间复杂度为 $O(nlogn)$。

堆排序中需要用到的数据结构是堆,它是一种特殊的二叉树。堆分为大根堆和小根堆,大根堆满足任何一个非叶子节点的值都不小于其子节点的值,小根堆则相反,任何一个非叶子节点的值都不大于其子节点的值。

堆排序的算法步骤

  1. 将待排序的序列构建成一个大根堆或小根堆。
  2. 将堆顶元素(最大值或最小值)与末尾元素交换,从而将最大值或最小值放到了末尾。
  3. 将剩余的序列重新构建成一个堆。
  4. 重复步骤 2 和步骤 3,直到整个序列排序完成。

Java 代码实现

我们以使用大根堆进行从小到大排序为例,以下为 Java 代码实现:

public static void heapSort(int[] arr) {
    int len = arr.length;

    // 构建大根堆
    for (int i = len / 2 - 1; i >= 0; i--) {
        adjustHeap(arr, i, len);
    }

    // 交换堆顶元素到末尾
    for (int i = len - 1; i > 0; i--) {
        swap(arr, 0, i);
        adjustHeap(arr, 0, i);
    }
}

private static void adjustHeap(int[] arr, int i, int len) {
    int temp = arr[i];
    for (int k = 2 * i + 1; k < len; k = 2 * k + 1) {
        if (k + 1 < len && arr[k] < arr[k + 1]) {
            k++;
        }
        if (arr[k] > temp) {
            arr[i] = arr[k];
            i = k;
        } else {
            break;
        }
    }
    arr[i] = temp;
}

private static void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

其中, adjustHeap 方法是用于调整堆的方法, swap 方法是交换元素的方法。

示例说明

以下为两个示例说明:

示例一

对数组 [4, 6, 8, 5, 9] 进行从小到大排序。

构建大根堆:

    4
  /   \
6      8

/ \
5 9

第一次交换堆顶元素到末尾:

    9
  /   \
6      8

/ \
5 4

重新构建堆:

    6
  /   \
5      8

/ \
4 9

第二次交换堆顶元素到末尾:

    8
  /   \
5      6

/ \
4 9

重新构建堆:

    6
  /   \
5      4

第三次交换堆顶元素到末尾:

    5
  /   \
4      6

重新构建堆:

    4

排序完成,数组变成了 [4, 5, 6, 8, 9]

示例二

对数组 [8, 7, 6, 5, 4, 3, 2, 1] 进行从小到大排序。

构建大根堆:

    8
  /   \
7      6

/ \ / \
5 4 3 2
/
1

第一次交换堆顶元素到末尾:

    1
  /   \
7      6

/ \ / \
5 4 3 2
/
8

重新构建堆:

    7
  /   \
5      6

/ \ / \
1 4 3 2
/
8

第二次交换堆顶元素到末尾:

    2
  /   \
5      6

/ \ / \
1 4 3 7
/
8

重新构建堆:

    6
  /   \
5      4

/ \ / \
1 2 3 7
/
8

第三次交换堆顶元素到末尾:

    3
  /   \
5      4

/ \ / \
1 2 6 7
/
8

重新构建堆:

    5
  /   \
1      4

/ \ / \
3 2 6 7
/
8

第四次交换堆顶元素到末尾:

    4
  /   \
1      2

/ \ / \
3 5 6 7
/
8

重新构建堆:

    3
  /   \
1      2

/ \ / \
4 5 6 7
/
8

第五次交换堆顶元素到末尾:

    2
  /   \
1      3

/ \ / \
4 5 6 7
/
8

重新构建堆:

    1
  /   \
4      3

/ \ / \
2 5 6 7
/
8

第六次交换堆顶元素到末尾:

    1
  /   \
2      3

/ \ / \
4 5 6 7
/
8

重新构建堆:

    2
  /   \
4      3

/ \ / \
5 1 6 7
/
8

第七次交换堆顶元素到末尾:

    1
  /   \
4      3

/ \ / \
5 2 6 7
/
8

重新构建堆:

    4
  /   \
5      3

/ \ / \
1 2 6 7
/
8

排序完成,数组变成了 [1, 2, 3, 4, 5, 6, 7, 8]

总结

堆排序相对于其他排序算法来说,其代码实现比较简单,空间复杂度比较小,时间复杂度较优秀。但是由于堆排序的算法思路和数组中数据的存储方式不同于其他排序算法,所以有时候可能会有一些不易于理解的地方。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java 数据结构之堆排序(HeapSort)详解及实例 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • 快速排序(整数)的C语言代码和JAVA代码

    一、问题描述 我们目前有一些数据,这些数据都是整数,然后我们现在需要做的就是把这些数据按照小到大排一下,然后输出出来。 二、问题的解决办法 首先确认一下分界点,我们常见的分界点是第一个点,第二个点,中间的一个点; 然后我们调整一下范围,也就说所有小于等于某个点的值在左半边,大于等于某个点的值在右半边。 递归处理左右两端。 案例如下: 我们首先手头有一些数据,…

    算法与数据结构 2023年4月18日
    00
  • mysql的Buffer Pool存储及原理解析

    下面我就来详细讲解一下“mysql的Buffer Pool存储及原理解析”的攻略。 Buffer Pool简介 在MySQL中,Buffer Pool是一个重要的概念,也可以说是MySQL最重要的性能优化建议之一。Buffer Pool是MySQL内存中缓存数据页的数据结构,用于加速数据的读写。 数据页 在MySQL中,数据是以数据页(page)为单位进行读…

    数据结构 2023年5月17日
    00
  • Go语言数据结构之插入排序示例详解

    Go语言数据结构之插入排序示例详解 什么是插入排序? 插入排序是一种简单直观的排序方法,其基本思想是将一个待排序的序列分成已排序和未排序两部分,从未排序的部分中选择一个元素插入到已排序部分的合适位置,直到所有元素都被插入到已排序部分为止。 插入排序示例 示例1 我们来看一个数字序列的插入排序示例: package main import "fmt&…

    数据结构 2023年5月17日
    00
  • 设要采用CRC编码传送的数据信息x=1001,当生成多项式为G(x)=1101时,请写出它的循环校验码。若接收方收到的数据信息x’ =1101,说明如何定位错误并纠正错误

    题目:设要采用CRC编码传送的数据信息x=1001,当生成多项式为G(x)=1101时,请写出它的循环校验码。若接收方收到的数据信息x’ =1101,说明如何定位错误并纠正错误 根据题目描述,需要采用CRC编码对数据信息x=1001进行编码,生成多项式为G(x)=1101。下面是计算循环冗余校验码的步骤:1.首先将数据信息x乘以x的次数,使得它的位数与G(x…

    算法与数据结构 2023年4月18日
    00
  • 【ACM算法竞赛日常训练】DAY10题解与分析【月月给华华出题】【华华给月月出题】| 筛法 | 欧拉函数 | 数论

    DAY10共2题: 月月给华华出题 华华给月月出题 难度较大。 ? 作者:Eriktse? 简介:211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?? 原文链接(阅读原文获得更好阅读体验):https://www.eriktse.com/algorithm/110…

    算法与数据结构 2023年4月17日
    00
  • C++数据结构之二叉搜索树的实现详解

    C++数据结构之二叉搜索树的实现详解 1. 什么是二叉搜索树? 二叉搜索树是一种二叉树,其中每个节点都包含一个键值,且每个节点的键值都大于其左子树中任何节点的键值,小于其右子树中任何节点的键值。如下图所示: 9 / \ 4 15 / \ 12 20 在上面的二叉搜索树中,节点的键值分别是9, 4, 15, 12, 20,且每个节点的键值都符合上述定义。 2.…

    数据结构 2023年5月17日
    00
  • [Week 19]每日一题(C++,数学,并查集,动态规划)

    目录 [Daimayuan] T1 倒数第n个字符串(C++,进制) 输入格式 输出格式 样例输入 样例输出 解题思路 [Daimayuan] T2 排队(C++,并查集) 输入格式 输出格式 样例输入1 样例输出1 样例输入2 样例输出2 样例输入3 样例输出3 数据规模 解题思路 [Daimayuan] T3 素数之欢(C++,BFS) 数据规模 输入格…

    算法与数据结构 2023年5月4日
    00
  • Javascript中扁平化数据结构与JSON树形结构转换详解

    一、扁平化数据结构 扁平化数据结构是指将一个JSON树形结构数据转换为一个扁平化的对象数组,通常用于在数据操作中进行遍历和检索,方便数据的处理和展示。 例如,有一个JSON树形结构数据如下: { "name": "中国", "children": [ { "name": &quo…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部