数据结构之堆排序

hello各位,今天我来讲一下堆排序,基于堆的一些简单实现我就在这里直接给大家了

1.堆实现的简单代码

2.堆排序的一些”妙“+.堆排序的代码实现

3.堆排序的时间复杂度

好,我们开始,run

1.堆实现的简单代码(这里我只出示函数的声明,具体实现很简单,大家自己写吧)

2.堆排序的一些”妙“

这里将是一个重点:

首先我们要认识到我们之前接触到的排序方法有选择排序,冒泡排序,qsort函数排序(注意:虽然这个函数的复杂度较低,但我们以现在的知识无法模拟实现)都是时间复杂度为0(n^2)的,所以一些大佬就根据堆的性质发现了一种时间度复杂度更低的排序方法。

堆排序分为两部:1.先建堆(这里如果我们是升序,我们选择建大堆;若我们是降序,我们选择建小堆)(我们下面会讲为什么)

一.建堆的代码实现(小堆)

这里又出现一个问题(我们是向上调整建堆呢,还是向下调整建堆呢,作为一名程序员,我们要考虑时间复杂度)

首先向上建堆是从树的第二行开始,每一个节点都要向上调整,我们假设这个满二叉树的高度为h,那节点数就为2^h-1,我们要最多向上调整2^h-2个节点,而且我们知道树的叶节点所在的一层节点数几乎就占了整个树节点数的一半,更何况所在的深度越深,向上调整的次数越多,可以说是”多的多做,少的少做”;而向下建堆的话我们的叶节点是不需要考虑的,那我们需要调整的节点个数减少,更妙的是深度越高的节点向下调整的次数越少,所以“少的多做,多的少做”所以我们可以看出向下建堆的效率更高一些,提倡哦!

向上调整建堆代码:(这里少了个断言指针a为空的情况)

向下调整建堆代码:(同上)

二.堆排序实现

这里我们来讲一下为什么要升序用大堆来排,降序用小堆来排

重点:

很多人会想我要升序,利用小堆选出最小的树(即堆顶)在,然后删除,然后再选出次小的数,然后再删除,这不完美吗?哈哈,大家仔细想一下,树的兄弟节点有大小关系吗?再者?如果删除了堆顶元素,剩下的元素已经不再是一个小堆,你又得重现建堆,建堆的复杂度(向下调整建堆是0(n),向上调整是0(n*logn)),然后你要建n次堆,时间复杂度最低为0(n^2),那我们学堆排序干嘛,只不过是用高级的零件干低效的事,所以这种方法不可行。

那肯定会有人问,那建大堆怎么就可以了?我来细细说:首先我们要明白前者不好的原因是删除了一个元素,使得剩下的不再是一个堆,要再次建堆,那我们就要想办法不删除,所以我们见大堆,建成后将堆顶的元素(即max)与堆最后一个节点交换,这样的话,我们可以保证堆顶以下的元素依然是堆,这样就可以规避多次建堆的问题了,然后我们只要一次向上调整,再次找出堆顶,再交换,就问你:妙不妙?

附上代码:

三.经过上面的讲解,堆排序的时间复杂度分为建堆和堆排序

堆排序0(time)=建0(time)+排0(time)=0(n)+0(n*logn);

所以其时间复杂度为0(n*logn)

  • 14
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值