8090要玩网 手游攻略 新游动态 堆排序的图形基本操作(两个)

堆排序的图形基本操作(两个)

时间:2025 07 17 13:09:56 来源:其他 浏览:0

大家好,今天来为大家分享堆排序的图形基本操作(两个)的一些知识点,和的问题解析,大家要是都明白,那么可以忽略,如果不太清楚的话可以看看本篇文章,相信很大概率可以解决您的问题,接下来我们就一起来看看吧!

堆排序的插图(a)堆和堆的特性是什么

1. 引言

在上一篇文章中,我们了解到堆分类面临两个主要问题:

1。构建一个序列,以大大的顶部堆;

2。删除大顶堆的根节点后,调整其剩余的节点以使它们形成新的大型顶部堆。

第一个问题也可以通过解决第二个问题来解决,因此让我们首先解释第二个问题。

2. 堆调整

2.1 算法概述

调整其剩余节点以将其重新形成堆中的过程称为堆调整。在这里,我们将以大型顶部堆为例介绍堆调整的过程,而小型堆调整的过程相似。

取出大顶堆的根节点后,将大顶堆的最后一个节点移至根节点位置作为新的根节点,如图1所示。目前,这款新的全二进制树的左和右子树仍然是大型顶部堆,但是新的根节点可能无法满足大型顶部堆的要求。这也是调整大顶堆的先决条件,即,完全二进制树的左右子树是大顶堆,只有根节点可能无法满足大顶堆的要求。

假设新的根节点目前符合大型顶部堆的要求,也就是说,其值大于或等于其左和右子节点的值,那么这个新的全二进制树已经已经是一个大型顶部堆,并且调整结束了。

但是,在图1中,新的根节点的值为39,比其左右子节点小,并且不符合大型顶部堆的要求(这种情况在图中以红色表示)。因此,需要调整根节点。

图1让最后一个节点成为新的根节点

如图2所示,选择根节点的较大一个子节点并将其与较大的子节点交换。交换后的新根节点必须是所有节点中最大的节点,因此它大于或等于其左右子。扎根于无需儿童节点的子树不受影响,它仍然是一个巨大的顶部堆。虽然另一个子树(现在与原始根节点扎根)可能不再是大顶堆。

在图2中,交换了根节点(值39)及其右子(值83),并且新的根节点(值83)大于或等于其左右子。左子树(扎根于值77)不受影响,仍然是大型顶部堆。右子树(现已扎根于值39)不再是一个大顶堆,因为值39小于其左子节点的值。

图2大型堆栈调整过程1

右边的子树以前是一个大顶堆,但仅交换其根节点,因此其左和右子树仍然是一个大顶堆,而只有其新的根节点不符合现在大型顶部堆的要求。因此,该子树现在还符合大型顶堆调整的先决条件,我们需要再次调整子树的新根节点。该子树的调整过程类似于先前的调整,如图3所示。

图3大型堆栈调整过程2

在图3中,子树的根节点的较大子节点(值39)是其左子节点(值61),因此两个节点交换了位置。交换后,值为39的节点形成只有一个节点的完全二进制树,也就是说,它没有左手的孩子,因此它符合大顶堆的要求。在这一点上,整个二手树也是一个大堆,因此调整过程已经结束。

堆排序的图形基本操作(两个)

2.2 算法实现

我们使用C语言来实现大型顶部堆调整算法,实现代码直接对应于我们上面的算法说明,并且该代码给出了非常详细的注释,因此该代码应易于理解。

在此实现中,有一个关注点,也就是说,当我们交换父节点及其较大的子节点时,我们只需将子节点的值写入父节点的位置,而无需将父节点的值写入子节点。这就是为什么在以下代码中评论第56行代码的原因。

这是因为在对父节点进行了调整后,它可能必须继续多次调整它,以便将其交换到的位置立即被其新子节点(较大的一个)覆盖。因此,只有在最后一刻将父节点写入最终调整以减少消费的位置的位置。以下代码中的第61行代码是为了实现此目标。

/** * Function: heapAdjust * Description: Implementation of the large top heap adjustment algorithm * param: array This sequence stores the complete binary tree to be adjusted to the large top heap * param: start The subscript of the root node of the completely binary tree in the sequence * param: end The subscript of the last node of the completely binary tree in the sequence * /void heapadjust(int array [],int start,int end){/* * parent代表要调整的节点的下标, *孩子是父母的子节点的下标, * temp用于交换节点的值。 */int parent; int儿童; int温度; /** *初始化parent的启动,因为在开始时,要调整的*节点是完全二进制树的根节点,并且root节点的下标开始了。 *将温度设置为根节点的值。 */parent=start; temp=array [start]; /***首先将孩子作为父节点的左子节点的下标,父节点的左子节点的下标是2* parent+1; */for(child=2 * parent + 1; child=end; end; end; child=2 * parent + 1){/** *如果孩子小于end,则父节点有一个正确的孩子,而正确的孩子的下标*是孩子+ 1;如果左子女小于右子女,请增加*孩子的价值,使其成为右子女的下标。 */if(child end arnay [child] array [child+1]){++ child; } /***目前,孩子是父节点较大的孩子的下标; *如果温度(这是父节点的值)大于或等于子节点的值, *则父节点已满足大顶堆的要求,调整已经结束, *此时,循环已退出。 */if(temp=array [child]){break; } /***否则,父节点的值小于子节点的值,并且需要交换它们; *交换后,将父级设置为子,因为父节点已将*移至其子节点位置。 */array [parent]=array [child]; //array [child]=temp;父=孩子; } //如果由父节点调整的最终位置不是其启动的位置,则将其写入(parent!=start){array [parent]=temp; }}

3. 堆构造

3.1 算法概述

要构建序列作为堆,我们只需要在序列的相应的完全二进制树中重复应用每个子树的堆调整算法。从原始序列的最后一个元素开始,通过每个元素迭代,每个元素到一个元素,都以该元素作为根节点对子树进行大型顶部调整。由于它正在从后到正面,每次元素都被遍历时,其左右子树已经是大顶堆,因此具有该元素的完整二进制树,因为可以直接使用根来调整大顶堆。将大顶堆调整到根节点(序列中的第一个元素)之后,将原始序列构造为大顶堆。

由于叶子节点没有子节点,因此扎根于叶子节点的子树本身就是一个大堆,因此我们可以从最后一个内部节点向前穿越。最后一个内部节点必须是最后一个节点的父节点(其下标是n-1),因此最后一个内部节点的下标是(n-1-1)/2。

假设原始序列为[35、52、61、39、29、96、83、43、77],让我们以示例来显示大型顶堆结构的完整过程。我们首先将序列表示为完全二进制树,因为该树总共有9个节点,因此最后一个内部节点的下标是3个。我们对扎根的源环的subtree进行了大的顶部堆调整,该子树是编号为3的,如图4所示。图4所示。

图4:调整大量节点的大顶堆,其中许多3。

然后,如图5所示,大型顶部堆调整是在扎根于节点编号2的子树上进行的。

图5:调整大型节点的大顶堆,其中数量为2。

然后,大型顶部堆调整是在扎根于节点编号1的子树上执行的,如图6所示。

图6:调整有数字1的节点的大顶堆

最后,在带有编号为0的节点的子树上执行大型顶部堆调整(实际上是整个二进制树),如图7所示。此时,整个序列都构造为大顶桩。

图7:数字0的节点的大型顶部调整

3.2 算法实现

我们还使用C语言来实现该算法来构建大型顶部堆。实现代码直接与我们上面的算法说明相对应,我们在代码中给出了非常详细的评论。由于堆结构基于堆的调整,因此需要在此处调用第2节中实现的heapadJust()函数。

在本实现代码中需要注意一件事。我们在第2节中说,其第三个参数端是要调整的完整二进制树的最后一个节点的下标(代表序列中要调整的大顶堆)。然后,当我们调整不同的子树时,第三个参数传递给heapadjust()函数应为序列中子树的最后一个节点的下标。

用户评论

淡抹烟熏妆丶

终于理解了堆的概念了!这篇图解讲解得真好,看得特别明白。以前一直不太懂堆的基本操作,现在看这篇文章感觉都豁然开朗啦~ 关键的地方用图示展示超级清晰,真是太棒了!

    有15位网友表示赞同!

Edinburgh°南空

说真的,我是学了算法多年的人,还是从这篇博文里学到新东西!对堆的理解确实可以更深入一些。比如“维持堆性质”这个点,以前不太在意,看了图解才明白它是如此的关键。希望以后还有更多这样的深入讲解!

    有18位网友表示赞同!

孤街浪途

我觉得这个标题写的有点片面性啊,仅仅只有堆的基本操作,却没有涉及其他重要概念,比如堆的适用场景、时间复杂度分析等。 尽管讲解得比较清晰,但还是有些地方不够深入。

    有15位网友表示赞同!

若他只爱我。

这种图解方式真的太牛逼了!一下子就让我看懂了堆排序是如何通过调整堆结构实现高效排序的。之前在教材上看到堆排序感觉很抽象,现在结合这个图解,感觉就像打开了新世界一样!

    有6位网友表示赞同!

掉眼泪

说实话,我一直觉得算法学得太枯燥了,但是看了这篇博文之后,我发现原来算法还可以这样有趣!这种图解方式确实能让学*更高效,更加生动直观。

    有8位网友表示赞同!

执拗旧人

标题说的是“图解堆排序(二)”,难道之前也写过一篇吗? 这里讲的基本操作真的有些过于简单了,对于初学者来说可能容易理解,但对有一定算法基础的人来说,可读性不高啊。 <br />希望作者能继续深入地讲解堆排序的实践应用场景以及它的优缺点比较。

    有11位网友表示赞同!

怪咖

我对堆这个数据结构一直都没啥概念,这篇博文终于让我明白了!堆的基本操作确实很重要,尤其是"插入元素"和"删除最大值"这两步。感觉掌握了这些就可以理解很多算法的原理了。

    有15位网友表示赞同!

♂你那刺眼的温柔

图解真的很棒!我以前就觉得堆排序不太好理解,看了这个解读以后,发现其实它很简单。堆的结构和逻辑都很清晰,尤其是用颜色区分不同的节点,这种标示方式真是太有帮助了!

    有13位网友表示赞同!

我要变勇敢℅℅

对于算法新手来说,这篇文章非常有用!讲解简单易懂,图例也很清晰。让我从头开始理解堆的概念,并掌握它的基本操作。 我觉得这样的学*方式比看书要好得多,更加直观形象。

    有16位网友表示赞同!

呆檬

我还是觉得代码实现才是最重要的啊,光靠图解说不清堆排序的细节。如果作者能附上一些C++或Python的代码例子,对于理解起来会更有帮助!

    有10位网友表示赞同!

夏至离别

我很惊喜地发现这篇博文解释了“堆性质”的维护过程,这真是我这个长期学*算法的人一直想知道的答案!过去我一直搞不明白如何保证堆有序,现在明白了。作者真是一位优秀的老师!

    有8位网友表示赞同!

余笙南吟

对于初学者来说,这篇文章确实写的很好,清晰易懂。不过我自己已经对堆排序有了较深的了解,所以这篇博文对我来说没有太多新内容。希望作者能写一些更加深入的博文,探讨堆排序的更高阶应用场景吧!

    有8位网友表示赞同!

执笔画眉

这个图解分析真的很棒! 之前我总觉得堆排序只是个名字听起来复杂的概念,现在看完这篇文章才明白它的设计原理和操作逻辑是如此巧妙。 作者真的把一个抽象的概念讲得生动形象!

    有16位网友表示赞同!

巷口酒肆

对于编程初学者来说,这篇文章可以算是入门级了!不过,我觉得如果能多添加一些关于堆在实际应用中的场景分析,会更加吸引人,也会更容易加深理解。 例如,解释一下堆是如何应用于优先队列等问题吧!

    有17位网友表示赞同!

海盟山誓总是赊

我很喜欢这种图解的教学方式,它让算法不再那么枯燥和无趣了!作者真的很有创意!希望以后还有更多这样有趣的博文讲解算法中的核心概念!

    有12位网友表示赞同!

拉扯

我还想进一步学*堆排序的效率分析以及与其他排序算法的对比。 有什么推荐资源吗? 作者能分享一下你对于堆排序更深入理解的方法吗?

    有11位网友表示赞同!

标题:堆排序的图形基本操作(两个)
链接:https://www.yaowan8090.com/news/xydt/46924.html
版权:文章转载自网络,如有侵权,请联系删除!
资讯推荐
更多
阴阳师4月22日更新内容:帝释天上线技能调整,红莲华冕活动来袭

阴阳师4月22日更新内容:帝释天上线技能调整,红莲华冕活动来袭[多图],阴阳师4月22日更新的内容有哪些?版本更新

2025-06-25
四川电视台经济频道如何培养孩子的学习习惯与方法直播在哪看?直播视频回放地址

四川电视台经济频道如何培养孩子的学习习惯与方法直播在哪看?直播视频回放地址[多图],2021四川电视台经济频

2025-06-25
湖北电视台生活频道如何培养孩子的学习兴趣直播回放在哪看?直播视频回放地址入口

湖北电视台生活频道如何培养孩子的学习兴趣直播回放在哪看?直播视频回放地址入口[多图],湖北电视台生活频道

2025-06-25
小森生活金币不够用怎么办?金币没了不够用解决方法

小森生活金币不够用怎么办?金币没了不够用解决方法[多图],小森生活金币突然就不够用的情况很多人都有,金币没

2025-06-25