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

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日

相关文章

  • C语言线性表顺序表示及实现

    C语言线性表顺序表示及实现 线性表的概念 线性表是一种数据结构,它是由n(n≥0)个数据元素a1,a2,…,an 组成的有限序列(元素个数为0时,称为空表),并且这些数据元素遵循一定的线性关系。 线性表的存储结构 线性表的存储结构有两种:顺序存储和链式存储。顺序存储指的是用一段连续的存储单元依次存储线性表的数据元素,线性表中的元素在物理位置上也是相邻的;…

    数据结构 2023年5月17日
    00
  • Golang Mutex互斥锁源码分析

    Golang Mutex互斥锁源码分析 介绍 Golang的Mutex互斥锁机制是一种非常重要的并发控制方式,它可以保证在同一时刻,同一共享资源只能被一个goroutine访问,其他的goroutine必须等待当前访问者释放锁之后才能访问该共享资源。 在使用Mutex机制时,需要进行锁定、解锁等操作,而这一过程是由Mutex的底层实现——sync包来完成的。…

    数据结构 2023年5月17日
    00
  • C语言编程数据结构基础详解小白篇

    C语言编程数据结构基础详解小白篇攻略 1. 确定学习目标 在学习过程中,需要明确学习目标。对于小白来说,首先要了解C语言的基本语法,同时也需要掌握常用的数据结构。 2. 学习基本语法 2.1 变量和数据类型 C语言的变量必须先定义后使用 常用的数据类型包括整型、字符型、浮点型等 2.2 控制流程 C语言中常用的控制流程包括条件语句和循环语句 条件语句包括if…

    数据结构 2023年5月17日
    00
  • C语言详细分析结构体的内存对齐规则

    C语言详细分析结构体的内存对齐规则 1. 什么是内存对齐 在计算机内存中,每个数据都需要分配一定的内存空间存储,这些空间的大小不一定相同。内存对齐就是要求每个数据按照某个规则,分配其所需的内存空间。 在C语言中,结构体是一种复合数据类型,由多个数据成员组成。结构体的数据成员排列顺序、数据类型均可能不同,因此需要内存对齐来规定内存空间的分配。 2. C语言中结…

    数据结构 2023年5月17日
    00
  • Redis的六种底层数据结构(小结)

    Redis的六种底层数据结构(小结) 简介 Redis是一种基于内存的高效键值存储数据库,它支持六种不同的数据结构来存储数据。这些结构旨在提供高速、灵活和功能强大的一系列功能。在学习Redis时,了解这些数据结构可以帮助您更好地使用Redis并更好地解决您的问题。 Redis的六种底层数据结构 Redis支持以下六种不同的数据结构: String (字符串)…

    数据结构 2023年5月17日
    00
  • Java数据结构之堆(优先队列)详解

    Java数据结构之堆(优先队列)详解 概述 堆是一种基于树的数据结构,它可以用来解决很多问题,例如排序、优先队列等。在堆中,每个节点的值都小于或等于它的子节点的值。堆分为两种类型:最大堆和最小堆。在最大堆中,根节点的值最大;而在最小堆中,根节点的值最小。 堆的操作主要有以下两种: 插入:将一个元素插入到堆中,需要维护堆的性质,即节点的值小于或等于子节点的值。…

    数据结构 2023年5月17日
    00
  • java实现队列数据结构代码详解

    Java实现队列数据结构代码详解 1. 队列数据结构简介 队列(Queue)是一种先进先出(FIFO)的数据结构,支持在一端插入元素,在另一端删除元素并返回删除的元素。其操作包括入队(enqueue)和出队(dequeue)。 2. 队列实现方法 队列可以通过数组或链表来实现。其中,数组实现的队列称为顺序队列,链表实现的队列称为链式队列。 2.1 顺序队列 …

    数据结构 2023年5月17日
    00
  • 8个简单部分开启Java语言学习之路 附java学习书单

    8个简单部分开启Java语言学习之路 如果你想要学习Java语言,但是不知道从何入手,在这里,我们将为你提供一份简单易懂的攻略,分8个步骤带你开启Java语言学习之路。 1. 安装Java开发工具 Java学习的第一步是安装Java开发工具,目前比较流行的Java开发工具有多种,例如Eclipse、Intellij IDEA、NetBeans等。本攻略以In…

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