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日

相关文章

  • 查询json的数据结构的8种方式简介

    查询json的数据结构的8种方式简介 在处理JSON数据时,经常需要提取特定的数据或获取某个属性的值。这时候就需要使用JSON的查询语言来进行查询操作。本文将介绍8种常用的JSON查询方式,帮助大家更方便、快捷地查询和分析JSON数据。 1. 点语法 使用点语法(.)查询JSON数据是最简单、最常用的方式,通过指定属性名来获取相应的值。例如,假设有以下的JS…

    数据结构 2023年5月17日
    00
  • 详解Java实现数据结构之并查集

    详解Java实现数据结构之并查集 简介 并查集是一种基于树型结构的数据结构,主要用于解决一些不交集问题。它支持两个操作: 合并两个元素所在的集合 判断两个元素是否在同一个集合中 在并查集中,每个节点都有一个指向其父节点的指针。如果一个节点的指针指向它本身,说明它是一个集合的根节点。 实现 我们用一个int类型的数组parent来表示每个节点的父节点。初始时,…

    数据结构 2023年5月17日
    00
  • C++数据结构与算法之反转链表的方法详解

    C++数据结构与算法之反转链表的方法详解 在C++中,反转链表是一种常见的数据结构与算法技巧。在本文中,我们将详细讲解反转链表的实现过程以及常见的两种反转方法。 基本定义 在开始讲述反转链表算法之前,我们先介绍一下链表的基本定义。 链表是一种数据结构,其中每个节点包含一个数据元素和一个指向下一个节点的指针。下面是一个简单的链表的节点结构定义: struct …

    数据结构 2023年5月17日
    00
  • java 数据结构单链表的实现

    Java中实现单链表数据结构通常需要以下几个步骤: 1. 定义节点类 首先需要定义一个节点类,用于表示链表中的一个节点。每个节点包含两个属性:data表示节点的数据,next表示节点的下一个节点。这两个属性都需要定义为public,以便后续操作的访问。 public class Node { public int data; public Node next…

    数据结构 2023年5月17日
    00
  • 基于C++详解数据结构(附带例题)

    基于C++详解数据结构(附带例题)攻略 简介 该攻略是基于C++编程语言详解数据结构的,主要涉及数据结构中的相关概念、操作以及例题演练。C++语言作为一种高性能的编程语言,对于开发数据结构问题具有很大的优势。 数据结构概念 数据结构基本概念 数据结构是计算机存储、组织数据的方式。具体来说,数据结构可以理解为计算机存储数据的一种方式,也可以看作是一些组织数据的…

    数据结构 2023年5月17日
    00
  • C语言从猜数字游戏中理解数据结构

    C语言从猜数字游戏中理解数据结构 介绍 在游戏和编程之间有着密切的关系。猜数字游戏是一个经典的小游戏,它也可以作为学习数据结构的一个好教材。 在猜数字游戏中,你可以根据计算机所选数字的提示来猜出正确的数字。这个游戏可以帮助你更好地理解数据结构和算法。 游戏规则 1.计算机系统选择一个要猜的数字。 2.你需要猜出这个数字,计算机每次将你的猜测数字与要猜的数字进…

    数据结构 2023年5月17日
    00
  • 在matlab中创建类似字典的数据结构方式

    当需要使用类似字典的数据结构时,Matlab中可以使用结构体来实现。结构体是一种有序的数据集合,每个元素都可以包含不同类型的数据(如字符串、数值等),并通过指定一个名称来唯一地标识该元素。 创建一个空结构体 使用struct函数可以创建一个空的结构体,可以使用下面的代码: st = struct; 添加键值对 可以将键值对添加到结构体中,可以使用下面的代码向…

    数据结构 2023年5月17日
    00
  • Java实题演练二叉搜索树与双向链表分析

    Java实题演练二叉搜索树与双向链表分析 题目描述 给定一个二叉搜索树,将它转换成一个排序的双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。 思路分析 对于一颗二叉搜索树,有以下性质: 若左子树不为空,则左子树上所有结点的值均小于它的根结点的值; 若右子树不为空,则右子树上所有结点的值均大于它的根结点的值; 左右子树也为二叉搜索树。 我们考虑…

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