微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

以排序方式遍历堆与 BST

如何解决以排序方式遍历堆与 BST

干杯,我遇到了一个我认为有点棘手的问题。 它指出,我们必须比较使用堆和 BST 以排序方式遍历所有元素的最坏情况时间复杂度。以下哪一项是正确的?

  1. BST 中的排序遍历速度更快
  2. 在堆中排序遍历速度更快
  3. 两者都是 O(n)
  4. 两者都是 O(nlogn)

使用有序遍历以排序方式遍历 BST 是 O(n),但是堆呢?我认为堆的构造方式让我们不知道如何以排序的方式遍历它的元素。这就是为什么堆用于快速最小/最大查找以及删除和插入的原因。但这就是它停止的地方。我认为我们也可以从它的构造方式中得出这一点,因为完整的二叉树是通过将键大于或等于当前节点的每个节点放置到右侧或左侧(每个节点大于或等于它的孩子)。我的思维方式正确吗?

此外,如果有人对堆排序感到困惑,我认为 (4) 只是一个技巧答案,与实际正确答案无关,所以我最终会回答 (1)。任何错误的假设?感谢您的时间!

解决方法

这里有一种方法可以了解为什么(在比较模型中)在时间 O(n) 内按排序顺序迭代二叉堆的项目是不可能的。给定任何一组 n 个元素,您可以使用 heapify 算法在 O(n) 时间内从它们构建一个堆。如果您可以在 O(n) 时间内按排序顺序遍历该堆,那么您可以通过简单地按顺序应用算法,在 O(n) 时间内对 n 个项目进行排序。事实上,这告诉你一些更强大的东西——任何(基于比较的)算法以排序的顺序迭代堆,在最坏和平均情况下都必须花费时间 Ω(n log n)。

可以在时间 O(n log n) 内按排序顺序迭代二叉堆的项,方法是复制堆并使用堆排序或使用辅助堆,如下所示:将根元素加入队列,然后反复从堆中出列并将节点的子节点入队。

从这个意义上说,选项 (1) 是正确的,因为与二叉堆的 O(n log n) 相比,BST 的中序遍历需要时间 O(n)。选项 (2) 是不正确的(尽管可以想象,对于小的二叉堆,由于引用的局部性,您会看到堆排序击败了 BST 的中序遍历)。选项 (3) 是错误的,因为在比较模型中堆迭代需要时间 Ω(n log n)。但奇怪的是,选项(4)也是正确的。是的,中序遍历需要时间 O(n),但由于 big-O 是上限,因此将其绑定为 O(n log n) 会不太精确,但在技术上并没有错误。但选项 (1) 可能是最好的。

,

你几乎自己回答了这个问题。您可以在线性时间内执行 BST 的中序遍历(,其中 n 是 BST 中的元素数)。堆不按顺序存储元素,它只允许您有效地访问和删除最小或最大元素(取决于它是最小堆还是最大堆)。对堆的元素进行排序的最好办法就是将它们一个一个地提取出来(这本质上是一种众所周知的排序算法,堆排序)。从堆中移除最小/最大元素需要 时间。因此,移除所有 n 个元素的成本为 。因此,如果元素在堆中,则遍历 BST 比对元素进行排序要快...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。