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

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语言线性表全面梳理操作方法

    C语言线性表全面梳理操作方法 线性表概述 线性表是一种常用的数据结构,是指数据元素之间存在一定逻辑顺序,每个元素都有唯一的前驱和后继。 线性表有两种存储方式: 顺序存储结构 和 链式存储结构。 顺序存储结构 顺序存储结构是指采用顺序存储方式存储线性表,即将线性表的元素依次存储在一段连续的存储空间内。 代码示例:创建顺序存储线性表 #define MaxSiz…

    数据结构 2023年5月17日
    00
  • Lua中使用table实现的其它5种数据结构

    Lua中使用table可以实现多种数据结构,除了Lua原生支持的数组、哈希表之外,我们还可以用table来实现其他五种数据结构,这些数据结构包括集合(Set)、队列(Queue)、双端队列(deque)、堆栈(stack)以及链表(List)。 Set 集合数据结构中的元素是无序的、不重复的。使用table来实现集合数据结构,可以将元素作为table的key…

    数据结构 2023年5月17日
    00
  • 排序算法之详解冒泡排序

    引入 冒泡排序顾名思义,就是像冒泡一样,泡泡在水里慢慢升上来,由小变大。 虽然冒泡排序和冒泡并不完全一样,但却可以帮助我们理解冒泡排序。 思路 一组无序的数组,要求我们从小到大排列 我们可以先将最大的元素放在数组末尾 再将第二大的数放在数组的倒数第二个位置 再将第三大的数放在数组的倒数第三个位置 以此类推 那么现在问题的关键就是如何将 第 n 大的数 放在 …

    算法与数据结构 2023年4月25日
    00
  • Java数据结构之图的路径查找算法详解

    Java数据结构之图的路径查找算法详解 什么是图? 在计算机科学中,图是一种非常常见的数据结构,用于表示图形和网络等概念。图由节点和边组成,其中节点表示实体,边表示这些实体之间的关系。节点和边可以表示各种各样的实体和关系,因此图在计算机科学中具有广泛的应用。 图的路径查找算法 路径查找算法是一个用途广泛的算法,它用于查找从一个节点到另一个节点的路径。在图中,…

    数据结构 2023年5月17日
    00
  • Java数据结构之图的基础概念和数据模型详解

    Java数据结构之图的基础概念和数据模型详解 简介 图是一种非常重要的数据结构,在计算机科学和实际应用中广泛使用。比如搜索引擎中的网页之间的链接关系就可以用图来表示和处理。在本文中,我们将详细讲解图的基础概念和数据模型。同时,我们将通过两个实例来进一步说明图的应用。 图的基础概念 什么是图 图是由若干个节点(顶点)和连接节点的边组成的一种数据结构。一个图可以…

    数据结构 2023年5月17日
    00
  • Java数据结构之简单链表的定义与实现方法示例

    Java数据结构之简单链表的定义与实现方法示例 什么是链表 链表是线性数据结构的一种,它是由一个个节点构成的,每个节点包含两个部分,一个是数据,另一个是指向下一个节点的引用,通俗的说,就像火车一样,每节火车都是一个节点,而每车头都指向下一节车厢。 链表的定义 Java中常用链表有单向链表和双向链表,单向链表每个节点只有一个指向下一个节点的引用,而双向链表每个…

    数据结构 2023年5月17日
    00
  • js实现无限层级树形数据结构(创新算法)

    要实现无限层级树形数据结构,可以使用递归算法来解决。以下是该过程的详细攻略: 步骤1:准备数据 为了演示无限层级树形结构,我们需要准备一组具有父子关系的数据。数据可以是任何格式,例如在子对象节点下添加一个名为children的数组即可。 例如,假设我们有以下数据: const data = [ { id: 1, name: "Node 1&quot…

    数据结构 2023年5月17日
    00
  • C语言编程数据结构线性表之顺序表和链表原理分析

    C语言编程数据结构线性表之顺序表和链表原理分析 线性表的定义 线性表是由n(n>=0)个数据元素a1、a2、…、an组成的有限序列,通常用(a1, a2, …, an)表示,其中a1是线性表的第一个元素,an是线性表的最后一个元素。线性表中的元素个数n称为线性表的长度,当n=0时,线性表为空表。 线性表的分类 根据存储结构,线性表可以分为顺序表…

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