当前位置: 首页 > news >正文

堆排序易错点

1.建堆和调整堆(插入和删除)

建堆和调整堆的过程是不一样的:

建堆

从非终端节点编号i\leq \left \lfloor n/2 \right \rfloor的结点开始依次建立大根堆,例如:

拿第2个图说,首先比较-1,7,从中选一个小的,即“-1”,再与父结点“7”比较。要比较两次。所以,某非终端节点有两个孩子要比较两次,有一个孩子只用比较一次。

插入

直接看一题:

可以很直观的看到和"建立堆"的区别,在第3个图中,18并不需要与13进行对比,直接与父结点对比即可。因为这个堆本来就是一个大根堆,也就是说:在插入之前,13本来就是确定比25小的了,所以直接将插入节点与父结点进行对比(比父结点大,肯定比13大了)。所以在插入数据时,只需要和父结点比较。

补充:

比较次数最多等于树的高度减1,因为树的高度为\left \lfloor log_{2}n \right \rfloor+1(或者\left \lceil log_{2}(n+1) \right \rceil),所以堆的向上调整的比较次数最多等于\left \lfloor log_{2}n \right \rfloor

所以插入一个新元素的时间复杂度为O(log_2{n}) ,建堆的时间复杂度为O(n)。

删除

删除的过程通过一个题体现:

看到第1个图,一些人可能会想,将大根堆的堆尾放到堆顶,那么22肯定比53小,只用比较53和其兄弟节点,如果其兄弟节点大于53,那么肯定大于22,为什么还要将53与34的较大者再与22进行比较?

这只是一种特殊情况,来看另一种情况:

如果这个图按上面的做法,直接将9,8对比,换父结点时,而不与父结点10对比,显然就错了。

所以删除操作,堆顶数据从上至下对比,如果其有两个孩子对比两次,如果其有一个孩子对比一次。对比次数还是主要看树高,时间复杂度为O(log2n)

2.不同的建堆方式

上面提到的建堆方式是给定序列直接调整成堆,再看一遍过程:

而某些题是给定序列依次插入空堆,那么过程就完全不一样了:

补充:二叉排序树与堆的差别

以小根堆为例,堆的特点是双亲结点的关键字必然小于或等于该孩子结点的关键字,而两个孩子结点的关键字没有次序规定。在二叉排序树中,每个双亲结点的关键字均大于左子树结点的关键字,均小于右子树结点的关键字,也就是说,每个双亲结点的左、右孩子的关键字有次序关系。这样,当对两种树执行中序遍历后,二叉排序树会得到一个有序的序列,而堆则不一定能得到一个有序的序列。

既满足大根堆要求又满足二叉排序树的要求的二叉树(除了单个结点):


http://www.mrgr.cn/news/36464.html

相关文章:

  • 今日不错的讲企业架构的好图
  • 2024年汉字小达人区级自由报名备考冲刺:最新问题和官模题练一练
  • R包:ggheatmapper热图
  • 17121 求二叉树各种节点数
  • 关于前端框架的对比和选择
  • 传统PC危险了,以后我只用云电脑了
  • 0基础学习HTML(二十一)总结
  • golang如何把微信支付结构体拼接为对参数按照key=value的格式,并按照参数名ASCII字典序排序
  • 1.5 测试用例
  • 国产OpenEuler与Centos全面之比较
  • Java | Leetcode Java题解之第436题寻找右区间
  • VB 实例:掌握 Visual Basic 编程的精髓
  • 高级java每日一道面试题-2024年9月26日-运维篇[分布式篇]-如何保证每个服务器的时间都是同步的?
  • 一组.NET MAUI绘制的开源控件 - AlohaKit
  • 读构建可扩展分布式系统:方法与实践15可扩展系统的基本要素
  • 2024必备中英互译利器全知道
  • 新版双向链表,添加了at, front, back, insert, emplace等为了兼容std.
  • Stable Diffusion绘画 | 插件-Addition Networks:单独控制LoRA
  • 【C++】继承(下)
  • Java | Leetcode Java题解之第437题路径总和III