为什么堆排序可以降低复杂度
2017-08-07 06:58
357 查看
前言: 事情的本质往往需要追根溯源,从最宏观去思考,会发现理解本质能事半功倍。举个例子:8个小球中有一个质量较轻,用天枰最少称几次能区分开?这种题的本质其实是对答案的搜索空间如何切分的问题,如果你知道天枰有三种状态,那最好的情况就是每次称量答案搜索空间能变为原来的1/3那肯定是最优的,这样看来2次就可以,9个球也是两次,27个球的话就要3次了。今天讨论下堆。
堆,这里单指数据结构中的堆。
它可以解决两个重要的问题:1 排序 2 优先级队列
为什么有了快速排序还要用堆排序呢?这是因为堆排序对n个元素排序,所花的时间不会超过O(nlogn)。
下面说一下我个人的感觉,有些时候,我们为了方便或者说偷懒,喜欢采用线性的结构进行排序,但是我们也经常遇到当大规模数据进行排序的时候,这个时候O(n*n)的时间复杂度是等不起的。而堆本质上是将线性结构的数据预处理成树形结构,从而将排序的查询限定在树高范围之内。不能不说这是伟大的创造。
优先级队列:这是一种支持随意插入和最小(最大)提取元素的数据结构,本来它是可以采用任意的形式实现的,我们可以用任意的排序来实现最小元素的提取,但是这样操作n次,时间复杂度会是O(n*n),所以才有了用堆来实现优先级队列的方案,可以说优先级队列和堆有不可分割的羁绊。
其实堆排序可以用优先级队列来实现的,将要排序的元素依次插入到优先级队列后,再一一提取出来。为什么还要提出堆排序呢?因为道高一尺魔高一丈,优先级队列毕竟还要至少和原数据等量的空间复杂度,而堆排序就很好的避免了这一点,用了常量空间就解决了这一问题。
以前不去想这些问题,是因为觉得能用就行了,最近感觉有时知其然而不知其所以然就会很迷茫,遇到实际问题解决起来比较吃力。其实堆就是一种思想,至于你怎么建立堆,怎样维持堆性质,也有很多种方法,只要理解了堆的本质,遇到实际中的问题才会去想怎样能更高效地解决它,才会联想到堆。
堆,这里单指数据结构中的堆。
它可以解决两个重要的问题:1 排序 2 优先级队列
为什么有了快速排序还要用堆排序呢?这是因为堆排序对n个元素排序,所花的时间不会超过O(nlogn)。
下面说一下我个人的感觉,有些时候,我们为了方便或者说偷懒,喜欢采用线性的结构进行排序,但是我们也经常遇到当大规模数据进行排序的时候,这个时候O(n*n)的时间复杂度是等不起的。而堆本质上是将线性结构的数据预处理成树形结构,从而将排序的查询限定在树高范围之内。不能不说这是伟大的创造。
优先级队列:这是一种支持随意插入和最小(最大)提取元素的数据结构,本来它是可以采用任意的形式实现的,我们可以用任意的排序来实现最小元素的提取,但是这样操作n次,时间复杂度会是O(n*n),所以才有了用堆来实现优先级队列的方案,可以说优先级队列和堆有不可分割的羁绊。
其实堆排序可以用优先级队列来实现的,将要排序的元素依次插入到优先级队列后,再一一提取出来。为什么还要提出堆排序呢?因为道高一尺魔高一丈,优先级队列毕竟还要至少和原数据等量的空间复杂度,而堆排序就很好的避免了这一点,用了常量空间就解决了这一问题。
以前不去想这些问题,是因为觉得能用就行了,最近感觉有时知其然而不知其所以然就会很迷茫,遇到实际问题解决起来比较吃力。其实堆就是一种思想,至于你怎么建立堆,怎样维持堆性质,也有很多种方法,只要理解了堆的本质,遇到实际中的问题才会去想怎样能更高效地解决它,才会联想到堆。
相关文章推荐
- 你可能不知道位图,但是它真的很有用,特殊情况可以使时间复杂度降低不是一两个档次那么简单...
- 白盒测试之圈复杂度,以及可以直接降低圈复杂度的10种重构技术
- 白盒测试之圈复杂度,以及可以直接降低圈复杂度的10种重构技术
- hdu4334 Trouble 合并集合可以降低复杂度阿啦啦
- hdu4334 Trouble 合并集合可以降低复杂度阿啦啦
- 为什么硅谷的工程师可以工作到40岁以上
- 为什么说蜘蛛侠在数学角度是可以实现的?
- 为什么开源可以提高程序员的编程技能?
- 为什么双绞线绞合可以减少相…
- CVPR17最佳论文-densenet 及 resnet :为什么可以消除梯度反向传播的梯度弥散问题
- c/c++ 数组是下标为什么可以是负值
- spinlock与linux内核调度的关系,那么为什么信号量保护的代码可以睡眠而自旋锁就不能呢?
- WebSocket 是什么原理?为什么可以实现持久连接
- 为什么(i++)不能做左值,而(++i)可以
- 为什么拥有spinlock的时候不可以sleep
- 为什么MongoDB可以替代MySQL?
- InetAddress为什么不能new而可以直接拿来用
- 做技术到底可以做到哪种地步-技术为什么越走越窄
- 比特币开发专题(为什么比特币和人民币可以等值兑换)
- 为什么原生JS可以直接使用ID名称来获取元素