堆排序原理及算法代码详解

堆排序原理及算法代码详解

堆排序属于一种选择排序,它的基本思想是利用堆这种数据结构来进行排序。

堆的概念

堆(Heap)是一个特殊的树形数据结构,它有以下两种类型:

  • 大根堆:每个节点的值都大于或等于其左右孩子节点的值。
  • 小根堆:每个节点的值都小于或等于其左右孩子节点的值。

通过对堆进行操作,可以得到堆排序算法。

堆排序的基本思想

  • 将待排序序列构造成一个大根堆。
  • 此时,整个序列的最大值就是堆顶的根节点。
  • 将它和堆数组的末尾元素交换,这样末尾就是最大值了。
  • 然后将剩余的n-1个元素重新构造成一个堆,这样就会得到n个元素中的次大值。
  • 如此反复进行交换、重建大根堆的操作,直到整个序列有序。

堆排序的算法实现

下面是基于python语言实现的堆排序算法代码:

# heapify函数为创建大根堆的过程
# 功能:将序列转化为大根堆
# i:表示一个根节点的下标
# n:表示序列的长度,保证待调整的左、右子树都已经是大根堆
def heapify(arr, n, i):
    largest = i  # 初始化根节点为最大值
    l = 2 * i + 1   # 左子节点的下标
    r = 2 * i + 2   # 右子节点的下标

    # 如果左子树下标在序列中 and
    # 左子树的值大于根节点的值
    if l < n and arr[i] < arr[l]:
        largest = l

    # 如果右子树下标在序列中 and
    # 右子树的值大于根节点和左子树的值
    if r < n and arr[largest] < arr[r]:
        largest = r

    # 如果最大值不是根节点,就交换它们
    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]  # 交换根节点和最大值
        heapify(arr, n, largest)

# heapSort函数为堆排序函数
# 功能:对整个序列进行排序
def heapSort(arr,n):

    # 构建大根堆
    for i in range(n // 2 - 1, -1, -1):
        heapify(arr, n, i)

    # 从末尾开始排序
    for i in range(n - 1, 0, -1):
        arr[0], arr[i] = arr[i], arr[0]    # 交换根节点和末尾元素
        heapify(arr, i, 0)    # 重新构造大根堆

堆排序示例说明:

将以下序列进行排序:[12, 11, 13, 5, 6, 7]

  • 构造大根堆,序列变为[13, 11, 12, 5, 6, 7],堆顶元素为13
  • 交换堆顶元素13和末尾元素7,此时序列变为[7, 11, 12, 5, 6, 13],排除末尾元素7后重新构造大根堆,序列变为[12, 11, 7, 5, 6],堆顶元素为12
  • 交换堆顶元素12和末尾元素6,此时序列变为[6, 11, 7, 5, 12],排除末尾元素6后重新构造大根堆,序列变为[11, 5, 7, 6],堆顶元素为11
  • 交换堆顶元素11和末尾元素5,此时序列变为[5, 6, 7, 11],排除末尾元素5后重新构造大根堆,序列变为[7, 6, 5],堆顶元素为7
  • 交换堆顶元素7和末尾元素5,此时序列变为[5, 6, 7],排除末尾元素5后重新构造大根堆,序列变为[6, 5],堆顶元素为6
  • 交换堆顶元素6和末尾元素5,此时序列变为[5, 6],排除末尾元素5后重新构造大根堆,序列变为[5],堆顶元素为5
  • 排序完成,最终序列为[5, 6, 7, 11, 12, 13]

以上是堆排序原理及算法代码的详细讲解,如有不明白的地方,可随时进行提问。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:堆排序原理及算法代码详解 - Python技术站

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

相关文章

  • 合并排序(C语言实现)

    合并排序(C语言实现) 合并排序是一种将待排序序列分成多个子序列,分别进行排序,然后再将排序后的子序列合并成整体有序序列的排序算法。使用递归实现时,该算法的时间复杂度为O(nlogn),因此被广泛应用。 实现步骤 合并排序可以用以下步骤来实现: 分治:将待排序序列从中间分成两部分,递归地对左右两部分进行排序。 合并:将两个有序子序列合并成一个有序序列。 在实…

    算法与数据结构 2023年5月19日
    00
  • 逐步讲解快速排序算法及C#版的实现示例

    逐步讲解快速排序算法及C#版的实现示例 1. 快速排序算法简介 快速排序算法是一种高效的排序算法,它的时间复杂度为 $O(nlogn)$。它的基本思想是通过一次划分将原问题分解为两个子问题,再对子问题进行递归解决,最终得到排序结果。 2. 快速排序算法核心思想 快速排序算法的核心思想是选取一个基准元素,将待排序的序列分成两部分,一部分比基准元素小,一部分比基…

    算法与数据结构 2023年5月19日
    00
  • C++实现冒泡排序(BubbleSort)

    C++实现冒泡排序(BubbleSort)攻略 冒泡排序是一种简单的排序算法,它会重复地比较相邻的两个元素,如果顺序错误就交换它们的位置,直到排序完成。下面是C++实现冒泡排序的步骤。 1. 理解冒泡排序的基本原理 冒泡排序的基本思路是将待排序的数组分为已排序的部分和未排序的部分,先从未排序的部分开始,进行比较相邻元素的大小,并交换位置,直到本轮最大的元素被…

    算法与数据结构 2023年5月19日
    00
  • C语言详细讲解qsort函数的使用

    C语言详细讲解qsort函数的使用 qsort函数简介 在C语言中,qsort函数是一个标准库函数,用于将一个数组排序。它使用快速排序算法,实现了高效的排序。qsort函数的原型定义如下: void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void…

    算法与数据结构 2023年5月19日
    00
  • 算法系列15天速成 第六天 五大经典查找【下】

    算法系列15天速成 第六天 五大经典查找【下】- 完整攻略 简介 本篇文章是算法系列15天速成中的第六天内容,主要是介绍五大经典查找的后三种查找算法:插值查找、斐波那契查找以及分块查找。在介绍每一种查找算法时都会包含具体的思路、复杂度和应用场景等内容。 插值查找 思路 插值查找是在二分查找的基础上优化的一种查找算法,它不是通过数组的中间元素进行查找,而是通过…

    算法与数据结构 2023年5月19日
    00
  • JS折半插入排序算法实例

    下面是介绍JS折半插入排序算法的完整攻略。 什么是折半插入排序算法? 折半插入排序是插入排序的一种改进算法,它的基本思路是利用二分查找找到某个待排元素在已排序序列中插入位置。 折半插入排序算法的时间复杂度为 O(nlogn),比普通插入排序 O(n^2)快。 折半插入排序算法实现步骤 折半插入排序算法的实现步骤如下: 从第二个元素开始,将整个序列分为已排序区…

    算法与数据结构 2023年5月19日
    00
  • 基于Go语言实现冒泡排序算法

    基于Go语言实现冒泡排序算法 什么是冒泡排序 冒泡排序(Bubble Sort)是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复地进行,因而得名“冒泡排序”。该算法因其简单的实现方式和易于理解的原理而广泛应用。 冒泡排序算法实现方式 冒泡排序的算法原理如下: 比较相邻的元素。如果第一个…

    算法与数据结构 2023年5月19日
    00
  • 算法系列15天速成 第二天 七大经典排序【中】

    下面我就详细讲解“算法系列15天速成 第二天 七大经典排序【中】”的完整攻略。 1. 概述 本篇文章主要介绍七大经典排序算法,分别是插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序和归并排序。本文将详细讲解每种排序算法的思路和实现方法,并会给出每种算法的优缺点以及适用场合。 2. 插入排序 插入排序是一种简单直观的排序算法。它的基本思想是,将一个数据…

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