【数据结构】向上调整建堆和向下调整建堆的天壤之别以及堆排序算法

这篇具有很好参考价值的文章主要介绍了【数据结构】向上调整建堆和向下调整建堆的天壤之别以及堆排序算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【数据结构】向上调整建堆和向下调整建堆的天壤之别以及堆排序算法  

💯 博客内容:【数据结构】向上调整建堆和向下调整建堆的天壤之别以及堆排序算法

😀 作  者:陈大大陈

🚀 个人简介:一个正在努力学技术的准前端,专注基础和实战分享 ,欢迎私信!

💖 欢迎大家:这里是CSDN,我总结知识和写笔记的地方,喜欢的话请三连,有问题请私信 😘 😘 😘

目录

向上调整

向上调整建堆 

向下调整 

 向下调整建堆

两种方法的天壤之别 

总结一下

堆排序 

向上调整

void AdjustUp(HPDataType* a, int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] > a[parent])
		{	
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			 break;
		}
	}
}

向上调整建堆 

	for (int i = 1; i < n; i++)
	{
		AdjustUp(a, i);
	}

向下调整 

void AdjustDown(HPDataType* a, int n, int parent)
{
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child+1< n && a[child + 1] > a[child])
		{
			child++;
		}
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}

	}
}

 向下调整建堆

for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, n, i);
	}

两种方法的天壤之别 

这两个建堆方法看似相同,实际却有着天壤之别。

具体的数值我们可以计算一下。

【数据结构】向上调整建堆和向下调整建堆的天壤之别以及堆排序算法

如图,二叉树的第h层有2^(h-1)个节点。

 向下调整建堆最坏的情况就是每个节点都需要调整。

第一层有1个节点,最坏的情况是每个节点向下移动n-1层,次数就是1*(n-1)次。

第二层有2个节点,最坏的情况是每个节点向下移动n-2层,次数就是2*(n-2)次。

以此类推。。。

第n-2层有2^(n-3)个节点,最坏的情况是每个节点向下移动两层,次数就是2^(n-3)次.

第n-1层有2^(n-2)个节点,最坏的情况是每个节点向下移动一层,次数就是2^(n-2)次。

总共的计算次数就是f(h)=2^0*(n-1)+2^1*(n-2)+……+2^(h-3)*2+2*(n-2)*1次

这个数字我们可以用错位相减法计算出来。

最后得到的结果F(h)= 2^h -1 - h

假设树的节点有N个。

那么根据公式,2 ^ h - 1= N。

把表达式往N上凑。

就得到F(N) = N - log(N+1)。

向下调整建堆的时间复杂度也就得出来了,log(N+1)的大小基本可忽略。

所以向下调整的时间复杂度是o(N)左右。

再来看向上调整建堆。

向上调整就没有这么优秀了。

【数据结构】向上调整建堆和向下调整建堆的天壤之别以及堆排序算法 假设树的高度是h,二叉树的最后一层就占了一半的节点。

 我们仍旧按最坏的情况来算。

最后一层的每个节点都需要向上调整h-1次,光最后一层调整的次数就已经有2^(h-1)*(h-1)次了。

光看这一层可以看出差距。

上一条讲的向下调整的特点是节点多的层级调整的次数少,是少乘多

而现在讲的向上调整恰恰相反。

节点多的层级调整的次数多,是多乘多,这就造成了时间复杂度的巨大差异。

同样来计算一下。

假设高度为h。

F(h)=2^1*1+2^2*2+……+2^(h-2)*h-2+2^(h-1)*(h-1)

同样使用错位相减,解得F(h) = 2^h * (h-2) + 2

因为 N = 2^h-1。

我们将F(h)换成关于N的式子,F(N) = (N+1) * (log(N+1) -2 ) + 2 。  

同样是忽略掉不重要的数据,它的时间复杂度大概是O(N*logN)它的量级比向下调整大了很多

所以一般情况下,我们建堆一般是用向下调整。

总结一下

建堆——向下调整建堆——时间复杂度:O(N)

建堆——向上调整建堆——时间复杂度:O(N*logN)

时间复杂度上向下调整建堆优秀很多,我们建堆一般就使用它。

堆排序 

void HeapSort(int* a, int n)
{
	、

	//向下调整建堆
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, n, i);
	}
//向下排序
	while (end>0)
	{
		Swap(&a[0], &a[end]);
		AdjustDown(a,end, 0);
		--end;
	}
}
  • 将待排序序列构造成一个大堆
  • 此时,整个序列的最大值就是堆顶的根节点。
  • 将其与末尾元素进行交换,此时末尾就为最大值。
  • 然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。
  • 可以看到在构建大顶堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了
  • 向下排序和上面向上调整建堆很像,时间复杂度都可以认为是O(N*logN)。

【数据结构】向上调整建堆和向下调整建堆的天壤之别以及堆排序算法文章来源地址https://www.toymoban.com/news/detail-463315.html

到了这里,关于【数据结构】向上调整建堆和向下调整建堆的天壤之别以及堆排序算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构:堆和堆排序

    1.顺序结构 顺序结构存储就是使用数组来表示一棵二叉树 , 一般使用数组只适合表示完全二叉树 ,因为不是完全二叉树会有空间的浪费。而 现实使用中只有堆才会使用数组来存储 。 二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。 2.链式结构 二叉树的链式存

    2024年01月17日
    浏览(36)
  • 数据结构(三)堆和哈希表

    本文是在原本数据结构与算法闯关的基础上总结得来,加入了自己的理解和部分习题讲解 原活动链接 邀请码: JL57F5 哈希表存储的是由键(key)和值(value)组成的数据。例如,我们将每个人的性别作为数据进行存储,键为人名,值为对应的性别, 一般来说,我们可以把键当成

    2024年01月17日
    浏览(41)
  • 【数据结构】5.大根堆和左高树

    大根树: 树中的每一个节点的值都大于或等于其子节点的值 大根堆: 既是大根树又是完全二叉树(增加了完全二叉树的限制条件)所以下图中只有(a)和(c)是大根堆 假设在下面大根堆中插入一个元素9,插入步骤如下,时间复杂度为O(height)=O(logn) 尝试插入在6号位置,如果新的

    2024年02月08日
    浏览(28)
  • 数据结构:堆的实现与建堆时间复杂度分析

    目录 前言 一.堆的介绍 1.堆的本质 2.堆的分类 二.堆的实现(以小根堆为例) 1.关于二叉树的两组重要结论: 2.堆的物理存储结构框架(动态数组的简单构建) 3. 堆元素插入接口(以小根堆为例) 堆尾元素向上调整的算法接口: 4.堆元素插入接口测试 5.堆元素插入接口建堆的时间复杂

    2023年04月19日
    浏览(40)
  • 【数据结构】深度剖析最优建堆及堆的经典应用 - 堆排列与topk问题

    🚩 纸上得来终觉浅, 绝知此事要躬行。 🌟主页:June-Frost 🚀专栏:数据结构 🔥该文章分别探讨了向上建堆和向下建堆的复杂度和一些堆的经典应用 - 堆排列与topk问题。 ❗️该文章内的思想需要用到实现堆结构的一些思想(如向上调整和向下调整等),可以在另一篇文章

    2024年02月08日
    浏览(49)
  • 通胀向下,价格向上

    号外: 教链内参2.10《内参:BTC真的存在春节模式吗?》 9号,美国劳工统计局BLS对1月份发布的2023年12月份通胀月环比数据进行了修订,下修了0.1%,从0.3%下调为0.2%。更骚气的是,还把前值也就是11月的数据给上修了0.1%,从0.1%上调为0.2%。 这样一来,通胀数据就从稳步上升变

    2024年02月22日
    浏览(40)
  • 数据结构之平衡二叉树的平衡调整

    1:LL型调整 2:RR型调整 3:LR型调整 4:RL型调整 5:总结 作者约定:将导致不平衡的结点称作 被破坏者 ,破坏了结点的平衡的结点成为 破坏者 ,经过调整可以让该树平衡的结点称为 调整结点 。 LL型不平衡调整方法:以调整结点为中心,进行右旋操作,就可以使树平衡。

    2024年02月09日
    浏览(46)
  • 多态的转型分为向上转型和向下转型

    Java中,多态指的是同一行为,具有多个不同表现形式。通过多态,可以消除类之间的耦合关系,提高程序的可扩展性和可维护性。但多态在调用方法时,父类中如果没有该方法,会出现编译错误。也就是说,如果没有进行类型转换,不能调用子类拥有,而父类没有的方法。编

    2024年02月02日
    浏览(34)
  • 【数据结构】二叉排序树——平衡二叉树的调整

    参考视频: 懒猫老师-数据结构-(59)平衡二叉树【互动视频】 (1)什么是平衡二叉树 平衡二叉树(Balanced Binary Tree)是一种特殊的二叉查找树,它的目的是保持树的高度尽量平衡,以保证查找、插入、删除等操作的时间复杂度为 O(log n)。 常见的平衡二叉树算法包括 AVL 树、红

    2024年02月04日
    浏览(39)
  • Java:什么是向上转型与向下转型(详细图解)

    目录 一、什么是向上转型 1、概念 2、代码示例 3、向上转型的优缺点 二、什么是向下转型 1、向下转型的概念 ​编辑 2、代码示例 三、向下转型的缺点及 instanceof 的使用 1、向下转型的缺点 2、instanceof的使用 向上转型就是 创建一个子类对象 ,将其 当成父类对象来使用 。

    2024年03月23日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包