Algorithm 堆与二进制搜索树(BST)

Algorithm 堆与二进制搜索树(BST),algorithm,binary-tree,heap,binary-search-tree,Algorithm,Binary Tree,Heap,Binary Search Tree,堆和BST之间的区别是什么 何时使用堆,何时使用BST 如果要以排序方式获取元素,BST是否优于堆?堆只保证较高级别的元素比较低级别的元素大(对于最大堆)或小(对于最小堆),而BST保证顺序(从“左”到“右”)。如果要排序元素,请使用BST。二叉搜索树使用以下定义:对于每个节点,其左侧的节点具有较小的值(键),其右侧的节点具有较大的值(键) 其中,作为堆,作为二叉树的实现使用以下定义: 如果A和B是节点,其中B是A的子节点,则A的值(键)必须大于或等于B的值(键)。即, 钥匙(A)≥ 键(B)

堆和BST之间的区别是什么

何时使用堆,何时使用BST


如果要以排序方式获取元素,BST是否优于堆?

堆只保证较高级别的元素比较低级别的元素大(对于最大堆)或小(对于最小堆),而BST保证顺序(从“左”到“右”)。如果要排序元素,请使用BST。

二叉搜索树使用以下定义:对于每个节点,其左侧的节点具有较小的值(键),其右侧的节点具有较大的值(键)

其中,作为堆,作为二叉树的实现使用以下定义:

如果A和B是节点,其中B是A的子节点,则A的值(键)必须大于或等于B的值(键)。即, 钥匙(A)≥ 键(B)

今天我考了同一道题,答对了。微笑……:)

何时使用堆以及何时使用BST

Heap在findMin/findMax(
O(1)
)方面更好,而BST在所有查找方面都很好(
O(logN)
)。两种结构的插入都是
O(logN)
。如果您只关心findMin/findMax(例如优先级相关),请使用heap。如果你想把每件事都安排好,就去英国夏令时


前几张幻灯片解释得非常清楚。

将数组中的所有n个元素插入BST takes O(n logn)。数组中的n个元素可以在O(n)时间内插入到堆中。这给了heap一个明确的优势

正如其他人所提到的,heap可以在O(1)中执行
findMin
findMax
,但不能在相同的数据结构中同时执行。然而,我不同意堆在findMin/findMax中更好。事实上,只要稍加修改,BST就可以在O(1)中同时执行
findMin
findMax

在这个修改后的BST中,每次执行可能修改数据结构的操作时,都要跟踪最小节点和最大节点。例如,在插入操作中,可以检查最小值是否大于新插入的值,然后将最小值指定给新添加的节点。同样的技术也可以应用于最大值。因此,这个BST包含这些信息,您可以在O(1)中检索它们。(与二进制堆相同)

在此BST(平衡BST)中,当您
pop min
pop max
时,要分配的下一个最小值是最小节点的后续值,而要分配的下一个最大值是最大节点的前置值。因此,它在O(1)中执行。但是,我们需要重新平衡树,因此它仍将运行O(logn)。(与二进制堆相同)

我很想在下面的评论中听到你的想法。谢谢:)

更新
有关使用BST模拟堆的更多讨论,请交叉参考类似问题。

BST在堆上的另一个用途;由于一个重要的区别:

  • 在BST中查找继任者和前任将花费O(h)时间。(平衡BST中的O(对数)
  • 在堆中时,将花费O(n)时间来查找某个元素的后续元素或前置元素
在堆上使用BST:现在,假设我们使用一个数据结构来存储航班的着陆时间。如果着陆时间差小于“d”,我们无法安排航班着陆。并假设许多航班计划在数据结构(BST或Heap)中着陆

现在,我们想安排另一个航班在t降落。因此,我们需要计算t与其后继者和前继者的差值(应该是>d)。 因此,我们需要一个BST来实现这一点,如果平衡的话,它可以快速在O(logn)中

编辑:

排序BST按排序顺序打印元素(按顺序遍历)需要O(n)个时间,而Heap可以在O(n logn)个时间内完成。
Heap提取min元素并重新堆化数组,使其在O(n logn)时间内完成排序。

摘要

          Type      BST (*)   Heap
Insert    average   log(n)    1
Insert    worst     log(n)    log(n) or n (***)
Find any  worst     log(n)    n
Find max  worst     1 (**)    1
Create    worst     n log(n)  n
Delete    worst     log(n)    log(n)
此表中的所有平均时间与最差时间相同,但Insert除外

  • *
    :在这个答案的任何地方,BST==平衡的BST,因为不平衡是渐近吸吮的
  • **
    :使用此答案中解释的简单修改
  • ***
    log(n)
    用于指针树堆,
    n
    用于动态数组堆
二进制堆相对于BST的优势

  • 插入二进制堆的平均时间是
    O(1)
    ,因为BST是
    O(log(n))
    这是堆的致命特性

    还有其他达到摊销(更强)的堆,如,甚至最坏的情况,如,尽管由于非渐近性能,它们可能不实用:

  • 二进制堆可以有效地实现在基于指针的树或仅基于BST的指针的树之上。因此,对于堆,如果我们能够承受偶尔的调整延迟,我们可以选择更节省空间的阵列实现

  • 二进制堆创建,
    O(n log(n))
    用于BST

BST相对于二进制堆的优势

  • 搜索任意元素是
    O(log(n))
    这是BST的杀手级功能

    对于堆,它通常是
    O(n)
    ,除了最大的元素是
    O(1)

堆相对于BST的“错误”优势

  • 堆是
    O(1)
    以查找max,BST
    O(log(n))

    这是一个常见的误解,因为修改BST以跟踪最大的元素并在该元素可能发生更改时更新它是很简单的:插入较大的交换时,删除时查找第二大交换。(提到)

    实际上,这是堆的限制