面试必备算法|图解堆排序(Python)

简介: Python堆排序图解。

堆排序

堆排序的思想

​ 堆排序是用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

​ 以大顶堆为例,现将列表构造成一个大顶堆,此时,整个列表的最大值就是堆顶的值。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序列表了。具体可以总结为下面的三个步骤:

  • 将无序列表构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
  • 将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
  • 重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个列表有序。

图解堆排序

​ 在了解堆排序之前我们需要先了解堆的概念。对于堆结构我们可以分为大顶堆和小顶堆两种:

  • 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
  • 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;

​ 大顶堆和小顶堆的结构如下所示:

在这里插入图片描述

​ 了解了大顶堆和小顶堆的含义之后,我们开始了解堆排序的过程,首先给出如下的一个无序列表,我们用堆的形式来表示这个列表。

  • 第一步:将无序列表构建成一个大顶堆

在这里插入图片描述

​ 对于这个堆我们的目的是构造出一个大顶堆,构造的过程中我们需要不断的比较每一个堆结构的大小关系,并切把大的元素调整为父节点,对于325三个元素组成的子堆举例:
在这里插入图片描述

​ 经过上述子堆的调整后,原堆的结构如下:

在这里插入图片描述

​ 继续用上述方法调整154三个元素组成的子堆:

在这里插入图片描述

​ 经过本次调整之后,我们发现整个堆的堆顶(5)已经是最大的了,但是调整之后的子堆123又变的混乱了,此时我们再一次对该子堆做调整:

在这里插入图片描述

​ 至此我们把最开始的无序列表构造成了一个大顶堆,接下来就要进行排序的操作了。

  • 第二步:将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;

​ 首先我们将堆顶元素5和末尾元素1做交换:

在这里插入图片描述

​ 进行完本次操作我们可以发现最大的元素5就被放倒了最后的位置,此时我们把5先抛除。

  • 第三步:重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个列表有序。

​ 对于剩下的列表[1342]继续按照第一步的方法构造出大顶堆,然后按照第二步的方法继续找到最大的元素即可,直到排序完成:
在这里插入图片描述
堆排序的性质

最优时间复杂度:$O(nlog_2n)$
最坏时间复杂度:$O(nlog_2n)$
稳定性:不稳定

堆排序的代码实现

lst = list(map(int, input().split(',')))


# 创建堆(调整堆)
def heapify(arr, n, i):
    largest = i
    l = 2 * i + 1  # left = 2*i + 1
    r = 2 * i + 2  # right = 2*i + 2

    if l < n and arr[i] < arr[l]:
        largest = l

    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)


# 堆排序
def heapSort(arr):
    n = len(arr)

    # Build a maxheap.
    for i in range(n, -1, -1):
        heapify(arr, n, i)

    # 一个个交换元素
    for i in range(n - 1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i]
        heapify(arr, i, 0)
    return arr


heapSort(lst)
相关文章
|
2天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
15 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
2天前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
11 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
2天前
|
机器学习/深度学习 人工智能 算法
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
蔬菜识别系统,本系统使用Python作为主要编程语言,通过收集了8种常见的蔬菜图像数据集('土豆', '大白菜', '大葱', '莲藕', '菠菜', '西红柿', '韭菜', '黄瓜'),然后基于TensorFlow搭建卷积神经网络算法模型,通过多轮迭代训练最后得到一个识别精度较高的模型文件。在使用Django开发web网页端操作界面,实现用户上传一张蔬菜图片识别其名称。
9 0
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
|
6天前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
23 2
|
15天前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
18 3
|
18天前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
61 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
23天前
|
机器学习/深度学习 算法 Java
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
|
存储 iOS开发 MacOS
100 个基本 Python 面试问题第四部分(57-68)
100 个基本 Python 面试问题第四部分
159 0
100 个基本 Python 面试问题第四部分(57-68)
|
监控 大数据 Python
100 个基本 Python 面试问题第七部分(91-100)
100 个基本 Python 面试问题第七部分
172 0
|
存储 Java 测试技术
100 个基本 Python 面试问题第六部分(81-90)
100 个基本 Python 面试问题第六部分
124 0