堆排序-Python实现

Python实现堆排序 堆排序(Heap Sort)是利用堆这种数据结构所设计的一种排序算法。堆的结构是一棵完全二叉树的结构,并且满足堆积的性质:每个节点(叶节点除外)的值都大于等于(或都小于等于)它的子节点。Python实现二叉树递归遍历堆排序先按从上到下、从左到右的顺序将待排序列表中的元素构造成一棵完全二叉树,然后对完全二叉树进行调整,使其满足堆积的性质:每个节点(叶节点除外)的值都大于等于(或都小于等于)它的子节点。构建出堆后,将堆顶与堆尾进行交换,然后将堆尾从堆中取出来,取出来的数据就是最大(或最小)的数据。 阅读详情

简述

堆排序(Heap Sort)是一种基于比较的排序算法,它利用堆这种数据结构所设计的一种排序算法。堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。

堆

堆排序中的堆有大顶堆、小顶堆两种。他们都是完全二叉树。

完全二叉树是指除了最后一层外,每一层都是完全填充的,并且最后一层的右边都是空的二叉树。大顶堆和小顶堆都是特殊的完全二叉树,它们的特点分别是每个节点的值都不小于(或不小于)其子节点的值,和每个节点的值都不大于(或不小于)其子节点的值。

将该堆按照排序放入列表

  • 大顶堆:所有的父节点的值都比孩子节点大,叶子节点值最小。root 根节点是第一个节点值最大公式表示:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
  • 小顶堆:和大顶堆相反,所有父节点值,都小于子节点值,root 根节点是 第一个节点值最小公式表示:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]

ok,了解了这些定义。接下来,我们来看看堆排序的基本思想及基本步骤。

堆排序基本思想及步骤

堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

在堆的结构中,堆中的最小值(最大值)总是位于堆的根结点。在堆排序中主要分为三步:
(1)创建大顶堆(BuildMaxHeap):将待排序元素列中的所有元素进行排列,生成一个大顶堆;
(2)将堆顶元素与末尾元素进行交换,将最大元素“沉”到元素列末端;
(3)调整顶堆,使其满足大顶堆定义;
(4)重复(2)(3)步骤,直至元素列有序。

以大顶堆为例

构造大顶堆

  • 如何调整
    我们从最后一个非叶子节点处开始调整。最后一个非叶子节点是最后一个叶子节点的父节点。
    若父节点的下标为 i ,那么左孩子节点下标为 i × 2 + 1,右孩子节点下标为 i × 2 + 2。
    设元素列的长度为 N,因为下标从0开始,所以最后一个叶子节点的下标是 N - 1。
    分两种情况:第一种是最后一个叶子节点是左孩子节点,那么 n - 1 = i × 2 + 1,即 i = n / 2 - 1
    第二种情况是最后一个叶子节点是右孩子节点(此时 n 是奇数)那么 n - 1 = i × 2 + 2,即 i = ( n - 1 ) / 2 - 1 = n / 2 - 1(向下取整)
    综上,最后一个非叶子节点的下标是 n / 2 - 1

  • 构造大根堆

    以升序排序序列 [20,50,20, 40, 70,10,80, 30,60]为例

    它对应的二叉树结构如下:

在我们的例子中,最后一个非叶子节点的下标是 9 / 2 - 1 = 3,因此调整顺序为:3–>2 -->1 -->0。

  1. 从最后一个父节点开始,将父节点、他所有的子节点中的最大值交换到父节点。父节点:3

  1. 将倒数第二个父节点同理交换,父节点:2

  1. 继续调整父节点:1

  1. 最后是根节点:0

  1. 注意很重要:务必注意-承接第3步。
    假设根节点值为:10, 当他和两个子节点70, 80。

父节点和两子节点中的大的(80)交换后位于父节点2:原来80的位置。

可是他还有子节点,且子节点中的值比根节点大,那就还需要以他为父节点构造一次,与子节点6 值为20交换一次。

同理在其他所有父节点的构造中都需要判断调整
忽略第五步。构造好的的大顶堆如下:

堆排序简略版

基本思路:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。可称为有序区,然后将剩余n-1个元素重新构造成一个堆,估且称为堆区(未排序)。这样会得到n个元素的次小值。重复执行,有序区从:1—>n,堆区:n–>0,便能得到一个有序序列了。
每次将堆顶(根节点)最的的元素和堆尾列表最后一个元素交换,80 和40交换
即上面说的堆区(未排序):n–>0最大元素(根节点),和有序区从:1—>n,最后一个元素交换

按照上面原理继续排序,70, 30 交换。然后调整堆

堆顶元素60尾元素20交换后–>调整堆

最后结果

堆排序-python代码实现

现在排序这么一个序列:list_ = [4, 7, 0, 9, 1, 5, 3, 3, 2, 6]

    """
    堆排序  heap_sort
    
                         4
                       /   \
                     7      0
                   /  \    / \
                 9    1   5   3
               / \   /
             3   2  6
    
    list_ = [4, 7, 0, 9, 1, 5, 3, 3, 2, 6]
    """

代码实现一

    def swap(data, root, last):
        data[root], data[last] = data[last], data[root]
    
    #调整父节点 与孩子大小, 制作大顶堆
    def adjust_heap(data, par_node, high):
    
        new_par_node = par_node
        j = 2*par_node +1   #取根节点的左孩子, 如果只有一个孩子 high就是左孩子,如果有两个孩子 high 就是右孩子
    
        while j <= high: #如果 j = high 说明没有右孩子,high就是左孩子
            if j < high and data[j] < data[j+1]: #如果这儿不判断 j < high 可能超出索引
                # 一个根节点下,如果有两个孩子,将 j  指向值大的那个孩子
                j += 1
            if data[j] > data[new_par_node]: #如果子节点值大于父节点,就互相交换
                data[new_par_node], data[j] = data[j], data[new_par_node]
                new_par_node = j #将当前节点,作为父节点,查找他的子树
                j = j * 2 + 1
    
            else:
                # 因为调整是从上到下,所以下面的所有子树肯定是排序好了的,
                #如果调整的父节点依然比下面最大的子节点大,就直接打断循环,堆已经调整好了的
                break
    
    
    # 索引计算: 0 -->1 --->....
    #    父节点 i   左子节点:2i +1  右子节点:2i +2  注意:当用长度表示最后一个叶子节点时 记得 -1
    #    即 2i + 1 = length - 1 或者 2i + 2 = length - 1
    #    2i+1 + 1 = length 或 2i+2 + 1 = length
    #    2(i+1)=length 或 2(i+1)+1 = length
    #    设j = i+1  则左子节点(偶数):2j = length 和 右子节点(基数):2j+1 = length
    #    2j//2 = j == (2j+1)//2 这两个的整除是一样的,所以使用length//2 = j 然后 i + 1 = j
    #    i = j-1  = length//2 -1  #注意左子节点:2i+1 //2 =i  而右子节点:(2i+2)//2 = i+1 
    
    # 从第一个非叶子节点(即最后一个父节点)开始,即 list_.length//2 -1(len(list_)//2 - 1)
    
    # 开始循环到 root 索引为:0 的第一个根节点, 将所有的根-叶子 调整好,成为一个 大顶堆
    def heap_sort(lst):
        """
        根据列表长度,找到最后一个非叶子节点,开始循化到 root 根节点,制作 大顶堆
        :param lst: 将列表传入
        :return:
        """
        length = len(lst)
        last = length -1  #最后一个元素的 索引
        last_par_node = length//2 -1
    
        while last_par_node >= 0:
    
            adjust_heap(lst, last_par_node, length-1)
            last_par_node -= 1  #每调整好一个节点,从后往前移动一个节点
    
        # return lst
    
        while last > 0:
            #swap(lst, 0, last)
            lst[0], lst[last] = lst[last],lst[0]
            # 调整堆让 adjust 处理,最后已经排好序的数,就不处理了
            adjust_heap(lst, 0, last-1)
            last -= 1
    
        return lst #将列表返回
    
    
    
    if __name__ == '__main__':
        list_ = [4, 7, 0, 9, 1, 5, 3, 3, 2, 6]
        heap_sort(list_)
        print(list_)
    
    
    #最后结果为:
    [0, 1, 2, 3, 3, 4, 5, 6, 7, 9]

代码实现二

    import math
    
    def heap_sort(a):
        al = len(a)
    
        def heapify(a, i):
            left = 2 * i + 1
            right = 2 * i + 2
            largest = i
            if left < al and a[left] > a[largest]:
                largest = left
            if right < al and a[right] > a[largest]:
                largest = right
    
            if largest != i:
                a[i], a[largest] = a[largest], a[i]
                heapify(a, largest)
    
        # 建堆
        for i in range(math.floor(len(a) / 2), -1, -1):
            heapify(a, i)
    
        # 不断调整堆:根与最后一个元素
        for i in range(len(a) - 1, 0, -1):
            a[0], a[i] = a[i], a[0]
            al -= 1
            heapify(a, 0)
        return a
    
    
    if __name__ == '__main__':
        list_ = [4, 7, 0, 9, 1, 5, 3, 3, 2, 6]
        heap_sort(list_)
        print(list_)
    
    
    #最后结果为:
    [0, 1, 2, 3, 3, 4, 5, 6, 7, 9]
【python算法系列四】堆排序算法 堆排序,就像它的名字一样,利用了堆的特性来进行排序。实现堆排序的思路是,把数组构建成一棵二叉树,并随着每次堆的变化更新堆顶的最大/最小值。堆排序的时间复杂度在所有情况下都是 O(nlgn),它也是一个不稳定的算法。在开始编写堆排序的程序之前,我们首先要了解“堆”的概念。 堆是一种数据结构,它是一种特殊的完全二叉树:如果这个堆是一个大顶堆(最大的元素在堆顶),那么每个节点上的元素都应该比它的子节点上的元素要大,最大的元素在根节点上;反之,如果是小顶堆,那么每个节点上的元素都应该比它的子节点小,最小的元素在根节 阅读详情

相关推荐

Python算法——堆排序

堆排序的时间复杂度为 O(n log n),其中 n 是数组的长度。它是一种原地排序算法,不需要额外的空间,因此非常适合排序大型数据集。原始数组:[9, 6, 5, 2, 8]

Echo_Wish 326

详解堆排序(python实现)

堆排序之python实现 1.首先要知道什么是堆: 简单来说 堆就是一颗完全二叉树,如下图这样,通俗的讲除了最后一个有孩子的节点可以有一个左孩子或者有左右两个孩子,其他有孩子的节点都必须有左右两个孩子。 完全二叉树在列表里面的存储顺序:tree_list=[1,2,3,4,5,6,7,8,9,10,11,12] 即从上至下 从左到右顺序存储 堆分为最大堆和最小堆: 1.最大堆:所有节点的值都比它的左右孩子节点值大,这就造成整个堆最大值必然在根节点。 2.最小堆:所有节点的值都比它的左右孩子节点值小,这就造

Game__Zero的博客 1707

保姆级教程:2026版Windows电脑换新,微信QQ聊天记录无损搬家(附路径修改避坑指南)

本文提供2026版Windows电脑换新时微信QQ聊天记录无损迁移的保姆级教程,涵盖最新版微信/QQ的存储路径修改和避坑指南。通过详细步骤和实战技巧,确保数据迁移过程中不丢失任何珍贵对话记录和文件,特别适合需要保留完整聊天记录的用户。

weixin_42629815的博客 2476

python实现堆以及堆排序

堆这种数据结构的应用场景非常多,其中最典型的便是堆排序,堆排序是一种原地的,时间复杂度为O(nlogn)的排序算法,在某些场景非常好用。

NangoGreen的博客 1726

Transformer模型详解(图解最完整版)

Transformer由论文提出,现在是谷歌云TPU推荐的参考模型。论文相关的Tensorflow的代码可以从GitHub获取,其作为Tensor2Tensor包的一部分。哈佛的NLP团队也实现了一个基于PyTorch的版本,并注释该论文。在本文中,我们将试图把模型简化一点,并逐一介绍里面的核心概念,希望让普通读者也能轻易理解。Transformer 与 RNN 不同,可以比较好地并行训练。

2501_91695094的博客 2698

coreldraw sp2精简版 x4_CorelDRAW X4下载-CorelDRAW X4 SP2 精简版_Win10镜像官网

CorelDRAW X4 SP2是一个专业图形设计软件,专用于矢量图形编辑与排版,借助其丰富的内容和专业图形设计、照片编辑和网站设计软件,您将能够随心所欲地表达自己的风格与创意,轻松创作徽标标志、广告标牌、车身贴和传单、模型绘制、插图描画、排版及分色输出等。CorelDRAW X4 SP2软件特色CorelDraw X4 相比两年前的 CorelDraw X3 加入了大量新特性,总计有50项以上,...

weixin_30346025的博客 8883

算法——python实现堆排序

python有一个内置的推排序模块,(在构建堆的时候,构建的是小根堆)若有错误与不足请指出,关注DPT一起进步吧!构造堆:从最后一个非叶子节点开始调整。关于二叉树的操作,其实核心就是。

m0_66925868的博客 1201

纽马克-贝塔法(Newmark-Beta Method)在结构动力学中的应用与实现

本文深入解析了纽马克-贝塔法(Newmark-Beta Method)在结构动力学数值计算中的核心原理与应用。作为经典的时间积分算法,它通过调节γ和β参数,在计算精度、稳定性与效率间取得平衡,尤其适用于地震响应、风振分析等工程场景。文章详细阐述了其数学内核、在有限元分析中的实现步骤,并对比了隐式与显式方案的适用场景,为工程师提供了关键的方法选择与参数调优指导。

weixin_29232121的博客 146

python实现堆排序

堆排序 概念: 二叉堆,二叉堆本质上是一种完全二叉树,可以分为最大堆和最小堆两种。最大堆:任何一个父节点的值都大于等于其子节点的值;最小堆:任何一个父节点的值都小于等于其子节点的值。 二叉堆的根节点叫堆顶,二叉堆的特点决定了最大堆的堆顶是整个堆数据中的最大值,最小堆的堆顶是整个堆数据中的最小值。 堆的自我调整: 插入节点:首先将节点插入到堆尾,然后判断新插入的节点与其父节点是否满足最大/小堆的概念...

scp_6453的博客 1040

案例分析|一篇文章带你看懂养鸡场智慧管理系统

养鸡场智慧管理系统是为了满足现代化养鸡业对精细化管理的需求而设计的一款专业软件。随着科技的发展和农业产业的升级,传统的手工记录和管理方式已无法满足高效、准确和实时的数据跟踪需求。本软件旨在通过集成各种功能模块,帮助养鸡场主实现从鸡苗孵化、饲养管理、饲料控制到销售结算等全链条的智能化操作。该系统的核心目标是提升养鸡场的运营效率和盈利能力,通过自动化数据处理,减少人工误差,节省时间和精力。例如,孵化报表和记录模块可以帮助管理者实时监控孵化过程,及时调整策略;

muyu2980的专栏 930

【系统架构设计师】预测试卷一:综合知识(75道选择题)

软件架构风格是描述某一特定应用领域中系统组织方式的惯用模式,架构风格反映领域中众多系统所共有的结构和 (48),强调对架构(49)的重用。 (48) A. 语义特性 B. 功能需求 C. 质量属性 D. 业务规则 (49) A. 分析 B. 设计 C.实现

数据知道的博客 7766

堆排序python实现_python如何实现堆排序(代码示例)

本篇文章给大家带来的内容是关于python如何实现堆排序(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。堆排序堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点(但是不保证所有左子树比右子树小反之亦然)。堆排序可以说是一种利用堆的概念来排序的选择排...

weixin_39872872的博客 499

堆排序的Python3实现

堆排序不仅是在面试很常见的考察题目,也是一种很重要的排序方法,通过堆排序,我们也能更好地了解堆这种数据结构的思想。 堆排序思想理论 堆排序涉及到的概念: 堆排序是利用 堆进行排序的 堆是一种完全二叉树 堆有两种类型: 大根堆 小根堆 两种类型的概念如下: 大根堆:每个结点的值都大于或等于左右孩子结点 小根堆:每个结点的值都小于或等于左右孩子结点 这里有一个自己常用的心得,对于树结构的描述,...

GQxxxxxl的博客 701

一步一步详解LSTM网络【从RNN到LSTM到GRU等,直至attention】

本文主要译至并加上了部分笔者的见解,对于全面理解LSTM有一定的帮助。

zik的博客 3077

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Python 算法 实现堆排序

文章目录堆排序堆排序1 堆(heap)2 堆排序算法3 利用堆实现优先队列 堆排序 参考书《算法导论》 排序是算法中最为基础的问题,这篇文章是关于堆排序算法的理论和python实现 堆排序 在算法导论(一)中有两种排序方法,分别是归并排序和插入排序。其中归并排序有较好的渐近运行时间,而插入排序有空间原址性。堆排序综合了这两种排序的优点。 空间原址性 空间原址性是指,假设对一个序列进行排序,保存在序列外的数是常数级的,就称其具有空间原址性。 1 堆(heap) 堆是一种特殊的数据结构。一般下常常看作二叉树的数

wxyice的博客 558

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

python堆排序法_python中堆排序算法如何实现?

在使用python中,你会遇到一个词,就是堆排序。那堆排序是什么呢?堆排序看字面意思是一种排序方法,那堆是什么呢?堆是一个近似完全二叉树的结构,并同时满足堆积的性质。其实堆排序是指利用堆这种数据结构所设计的一种排序算法。认识了堆排序,那你知道堆排序在python中如何实现吗?本文小编就像大家演示推排序在python的实现代码。代码:defheap_sort(array,n,length):l...

weixin_39613951的博客 151

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

堆排序python代码实现_堆排序Python实现

def heap_sort(nos):global sizesize = len(nos)print "the size of the List is : %d " %sizeBuild_heap(size,nos)for i in range(size-1,0,-1):nums[0],nums[i] = nums[i],nums[0]size = size-1print "\n", numshe...

weixin_39848998的博客 180

堆排序 python实现

堆排序 python实现简介思路分析代码引用 简介 堆排序(Heap Sort)是利用堆这种数据结构而设计的一种排序算法,堆是一个近似于完全二叉树的结构,并同时满足堆积的性质:子节点的键值总是小于(或大于)它的父节点。堆排序是一种选择排序,它是一种不稳定排序。 思路 在堆的结构中,堆中的最小值(最大值)总是位于堆的根结点。在堆排序中主要分为三步: (1)创建大顶堆(BuildMaxHeap):将待...

xuweinan5的博客 1580

堆排序Python实现

堆排序Python实现 实现步骤: 1.创建堆。这一步主要是实现创建一个大(小)根堆 2.调整堆。交换堆顶与堆末尾元素,然后调整堆使堆继续变成大(小)根堆 3.堆排序。利用上面2步完成堆排序的实现 # -*- coding:UTF-8 -*- def heapInsert(arr, index): """ 对第i个元素进行插入,然后进行调整,把它变成大根堆 """ while arr[index] > arr[int((index - 1) / 2)]:

qq_32700493的博客 176

堆排序python代码实现,堆排序Python实现

def heap_sort(nos):global sizesize = len(nos)print "the size of the List is : %d " %sizeBuild_heap(size,nos)for i in range(size-1,0,-1):nums[0],nums[i] = nums[i],nums[0]size = size-1print "\n", numshe...

weixin_29367347的博客 101

用python实现堆排序

用python实现堆排序 前几天,写了用python实现十大经典排序,但是后面三个都是照搬百度,自己也没有很好的理解堆这个数据结构,现在又来埋坑了。 什么是堆?堆这种数据结构应用场景非常多,所以还是必须熟练掌握的。 在了解堆之前,我们需要了解一下,什么是完全二叉树 完全二叉树 下面是百度的定义: 一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。 看完这个,是不是有

胖大xian 2259
上一篇: parse库,一个优雅的python库
下一篇: 60行python代码带你了解刘谦春晚魔术的奥秘
海哥python
博客等级 码龄9年 1487粉丝 74原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海哥python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值