Go 数据结构之堆排序示例详解

yizhihongxing

Go 数据结构之堆排序示例详解

什么是堆?

堆(Heap)是一种特殊的树形数据结构,它满足下列性质:

  1. 堆中每个节点的关键字都不大于(或不小于)其子节点的关键字。
  2. 堆中,根节点(顶端)是最小或最大元素。

堆实际上是一个完全二叉树,因此可以用数组实现。对于下标为i的节点,其左子节点为2i,右子节点为2i+1,父节点为i/2。

堆分为最大堆和最小堆。在最大堆中,父节点的值大于子节点的值;在最小堆中,父节点的值小于子节点的值。

堆的时间复杂度为O(logN)。

堆排序的过程

堆排序是利用堆进行排序的方法。排序过程分为两个步骤:建立堆和排序。

建立堆

建立堆的过程是将无序的数组构建成一个堆。这个过程可以使用自下而上的方法从最后一个节点开始构建,由于堆中不存在孙子节点,因此可以忽略孙子节点的排列。

示例一:

func buildHeap(arr []int) {
    n := len(arr)
    for i := n / 2 - 1; i >= 0; i-- {
        heapify(arr, n, i)
    }
}

func heapify(arr []int, n, i int) {
    max := i     // 找到父节点、左节点、右节点中的最大值
    l, r := 2*i+1, 2*i+2
    if l < n && arr[l] > arr[max] {
        max = l
    }
    if r < n && arr[r] > arr[max] {
        max = r
    }
    if max != i {   // 如果最大值不是父节点,则交换父节点和最大值
        arr[i], arr[max] = arr[max], arr[i]
        heapify(arr, n, max)    // 递归地对最大值所在的子树进行堆化
    }
}

在上面的代码中,buildHeap()函数从最后一个节点的父节点开始进行堆化,调用heapify()函数进行堆化。

heapify()函数用于将一个节点及其子树堆化。首先找到父节点、左节点、右节点中的最大值,如果最大值不是父节点,则交换父节点和最大值,并递归地对被交换的子节点进行堆化。

排序

建立好堆之后,进行排序的过程就是将堆顶元素(最小或最大值)与数组的最后一个元素交换,然后将堆的大小减1,并对新的堆顶进行堆化。重复这个过程直到堆的大小为1。

示例二:

func heapSort(arr []int) {
    n := len(arr)
    buildHeap(arr)  // 先建立堆
    for i := n - 1; i > 0; i-- {
        arr[0], arr[i] = arr[i], arr[0]     // 将堆顶元素(最小值)与最后一个元素交换
        heapify(arr, i, 0)  // 对新的堆顶进行堆化
    }
}

在上面的代码中,heapSort()函数在建立好堆之后,对堆进行排序,在每一次循环中,将堆顶元素与数组的最后一个元素交换,并对新的堆顶进行堆化。

总结

堆排序是一种简单、高效的排序算法。它利用了堆的特点,建立和操作起来都比较容易。在建立堆的过程中,可以选择自下而上的、或自上而下的方法进行堆化。在排序过程中,每次将堆顶元素(最小或最大值)与数组的最后一个元素进行交换,而不必临时占用额外的空间。由于堆的时间复杂度为O(logN),因此堆排序的时间复杂度为O(NlogN)。

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

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

相关文章

  • R语言数据结构之矩阵、数组与数据框详解

    R语言数据结构之矩阵、数组与数据框详解 在R语言中,矩阵、数组和数据框是常见的数据结构。本文将从定义、创建、访问和操作等方面详细讲解这些数据结构。 矩阵(matrix) 定义 矩阵是R语言中的一种二维数据结构,所有的元素都必须是同一类型的,并且矩阵中的行列数必须相同。矩阵可以使用matrix函数创建。 创建 # 创建一个3行4列的矩阵,所有元素都为0 mat…

    数据结构 2023年5月17日
    00
  • C语言近万字为你讲透树与二叉树

    C语言近万字为你讲透树与二叉树 什么是树? 树是一种用来组织数据的非线性数据结构,它由一个根节点和若干个子节点组成,并且每个节点可能有若干个子节点。 什么是二叉树? 二叉树是一种特殊的树,它的每个节点最多只有两个子节点,并且分别称为左子节点和右子节点,左子节点在二叉树中永远排在右子节点的前面。 二叉树的遍历方式 二叉树的遍历方式有三种: 前序遍历(preor…

    数据结构 2023年5月17日
    00
  • Java 超详细图解集合框架的数据结构

    下面是完整攻略: Java 超详细图解集合框架的数据结构 简介 集合框架是Java中最基础的数据结构之一,是大部分Java程序员必须掌握的基础知识。这个框架提供了常用的数据结构和算法,包括List、Set、Map等等。本文将带领您从数据结构的角度详细解析Java集合框架中的各种数据结构,让您能够清晰地掌握它们的特点和使用方法。 数据结构 Java集合框架中的…

    数据结构 2023年5月17日
    00
  • Java数据结构与算法实现递归与回溯

    Java数据结构与算法实现递归与回溯攻略 什么是递归与回溯 递归是指函数调用自己的过程。在递归过程中,一般需要包含两个部分:递归调用过程和递归出口。递归应用广泛,例如在计算机科学中,递归可应用于算法设计中的分治思想和动态规划。 回溯是指在解决问题时,尝试每一种可能的分步方法,当尝试后发现该方法不行时,取消当前尝试的分步方法,回到上一步,再使用其他可能的分步方…

    数据结构 2023年5月17日
    00
  • 一起来看看C语言线性表的线性链表

    一起来看看C语言线性表的线性链表攻略 线性链表概述 线性链表是线性表的一种实现方式,它通过每个节点中包含指向下一个节点的指针来实现表中元素之间的链接,可以动态地增加、删除节点。线性链表分为带头节点的链表和不带头节点的链表,其中带头节点的链表更为常见。 实现思路 结构体定义 我们可以定义一个结构体来表示每个节点,例如: typedef struct ListN…

    数据结构 2023年5月17日
    00
  • 举例讲解C语言程序中对二叉树数据结构的各种遍历方式

    那么我们先来介绍一下二叉树。 什么是二叉树? 二叉树是一种树状的数据结构,它的每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树节点的定义如下: typedef struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NUL…

    数据结构 2023年5月17日
    00
  • C++数据结构的队列详解

    C++数据结构的队列详解 队列是什么? 队列是一种先进先出(First In First Out, FIFO)的数据结构,类似于现实生活中的排队等待服务。 队列中的数据按照先进先出的原则被处理。新的元素只能被插入在队列的末尾,而旧的元素只能从队列的开头被删除。因此,队列的末尾称为队尾,队列的开头被称为队头。 队列的实现方式 数组实现方式 队列可以使用数组实现…

    数据结构 2023年5月17日
    00
  • C语言数据结构之堆排序的优化算法

    C语言数据结构之堆排序的优化算法攻略 堆排序简介 堆排序(HeapSort)是一种树形选择排序,在排序过程中始终保持一个最大堆,每次将堆顶元素与最后一个元素交换位置,并进行一次最大堆调整操作,直到整个序列有序为止。 堆排序的时间复杂度为O(nlogn),具有不需额外存储空间的特点,因此广泛应用于内存受限的场景。 堆排序的优化算法 1. 建堆操作的优化 将序列…

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