除了优先级队列的明显答案之外,什么时候堆在我的编程冒险中会有用?
答案 0 :(得分:109)
每当您需要快速访问最大(或最小)项时使用它,因为该项始终是数组中的第一个元素或树的根。
但是,数组的其余部分保持部分未排序。因此,只能对最大(最小)的项目进行即时访问。插入速度很快,因此它是处理传入事件或数据的好方法,并且始终可以访问最早/最大的。
对优先级队列,调度程序(需要最早的项目)等有用...
堆是一个树,其中父节点的值大于其任何后代节点的值。
如果您认为堆是按深度线性顺序存储的二叉树,首先是根节点(然后是该节点的子节点,然后是那些节点的子节点);然后索引N处的节点的子节点为2N + 1和2N + 2。此属性允许快速访问索引。而且由于堆叠是通过交换节点来操纵的,因此可以进行就地排序。
答案 1 :(得分:40)
堆是允许快速访问最小或最大的结构。
但你为什么要这样呢?您只需检查添加上的每个条目,看看它是最小的还是最大的。通过这种方式,您可以始终拥有最小或最大的恒定时间O(1)
。
答案是因为堆可以让你拉最小或最大,并快速知道NEXT最小或最大。这就是为什么它被称为优先级队列。
假设您有一家医院,患者根据其年龄参加。无论他/她何时进入队列,最老的人总是先出席。
你不能只跟踪最老的那个,因为如果你拉出他/她,你就不知道下一个最老的那个。为了解决这个医院问题,您实施了最大堆。根据定义,此堆是部分排序的。这意味着您无法按年龄对患者进行排序,但您知道最老的患者总是位于顶部,因此您可以在恒定的时间O(1)
内拉出患者,并在对数时间内重新平衡堆{{1} 1}}。
假设您有一系列整数,并且想要跟踪O(log N)
。中位数是有序数组中间的数字。
示例:
median
在上述情况下,[1, 2, 5, 7, 23, 27, 31]
是中位数,因为包含较小数字7
的数组与包含较大数字[1, 2, 5]
的数组大小相同。通常,如果数组具有偶数个元素,则中位数是中间2个元素的算术平均值,例如[23, 27, 31]
。
现在,您如何跟踪中位数? 有2个堆,一个包含小于当前中位数的数字的最小堆和包含大于当前中位数的数字的最大堆。现在,如果这些堆总是平衡的,那么2个堆将包含相同数量的元素,或者一个元素将比另一个元素更多,最多。
当您向序列中添加新元素时,如果该数字小于当前中位数,则将其添加到最小堆中,否则,将其添加到最大堆中。现在,如果堆不平衡(一个堆比另一个堆多1个元素),则拉最大堆中的元素,添加到最小堆。现在他们是平衡的。
答案 2 :(得分:12)
堆的特性是它是一个保持数据半静态的结构;因此,在维持完整订单的成本与通过随机混乱进行搜索的成本之间进行良好的权衡。该特性用于许多算法,例如选择,排序或分类。
堆的另一个有用特性是它可以从数组就地创建!
答案 3 :(得分:3)
也适用于选择算法(找到最小值或最大值)
答案 4 :(得分:3)
当你对临时列表进行排序时,你应该考虑堆。
答案 5 :(得分:0)
如果要分别访问最小和最大的元素,可以使用minHeap或maxHeap。