【问题标题】:Insertion of a new element in Binary Max Heap在 Binary Max Heap 中插入新元素
【发布时间】:2018-06-21 08:14:37
【问题描述】:

考虑将元素插入 MaxHeap 的过程,其中 MaxHeap 由数组表示。假设我们对从新叶子到根的路径进行二分查找以找到新插入元素的位置,执行的比较次数为:

A) Θ(logn)

B) Θ(loglogn)

C) Θ(n)

D) Θ(nlogn)

================================================ ============================

假设我把 Max Heap 作为

                               100
                              /    \
                            80       90
                            /\       /\
                           50 40    70 60

现在说我插入了一个新元素 250,它将添加到最后一个叶节点,如下所示 -

                                100
                              /    \
                            80       90
                            /\       /\
                           50 40    70 60
                           /
                          250

现在通过添加 250 个最大堆属性被违反,我必须调用最大堆,这将花费 O(log n),但我的问题是现在数组没有排序,正如你从最大堆中看到的那样,那么如何我们完全应用二进制搜索吗?

看到数组是 100|80|90|50|40|70|60|250 和从叶子到根的路径
包含节点为 100|80|50|250 并且这不是排序数组,那么,我们如何应用二分查找?

另一个例子 - 如果我添加了一个不会违反最大堆属性的新元素,比如我添加了新元素 30,那么数组将按降序排序,我可以应用二进制搜索。

那么,我应该如何在考试中解决这个问题?

【问题讨论】:

  • 请注意,每条路径都已排序。
  • 二进制堆数组不应该排序
  • "max heaping" 不使用二分查找。 O(log n) 的复杂性与“改进的”二叉树的高度有关 - 通过将索引除以 2 并与该位置的元素进行比较,您逐渐向根移动
  • @YvesDaoust 每条路径是如何排序的?哦,意思是,当我添加新元素 250 时,从叶子(250)到根(100)的路径没有排序。
  • @YvesDaoust 没有其他方法可以添加 1 个元素。您应该破坏堆属性并通过 heapify 恢复它。为了外面的世界,应该是同步操作的,但还是..

标签: arrays algorithm data-structures heap


【解决方案1】:

鉴于这个最大堆:

                               100
                              /    \
                            80       90
                            /\       /\
                           50 40    70 60

您知道新元素 250 必须插入到路径 [100, 80, 50] 的某处。您知道,因为在标准堆插入方法中,您将新项目添加到数组中的第一个空闲位置,然后将其筛选到堆中。在这种情况下,您将在位置 7 添加它,并且到根的路径是 7 -> 3 -> 1 -> 0。

如果您应用二分搜索来确定该项目将沿该路径插入的位置,您会发现它必须在值 100 之前。

我认为这个问题旨在测试您对堆属性的了解。在 n 个项目的堆中,有 log(n) 个级别。我们称这个值为 h。从根到最后一级项目的路径将包含 h 个项目。二分搜索已知为 O(log n)。或者,在这种情况下,O(log h)。由于 h == log(n),所以答案是 O(log log n)。

【讨论】:

  • 再次非常感谢,先生! P.S - 我已经更改了我的显示名称,在我的后续任务中不要忘记我! @JimMischel:P
  • 如果您应用二分搜索来确定该项目将沿该路径插入的位置,您会发现它必须在值 100 之前。 先生,怎么做你这么说,我的意思是,你是在对数组的索引 7 - 3 - 1 - 0 应用二进制搜索吗?但又一次数组未排序,二进制搜索只能应用于排序数组。因此,您如何计算 250 将插入到 100 之前?我只能说,在节点 250 上应用 Max heapify 之后,它就变成了根节点和它下面的 100。
  • 对从根到任何特定叶节点的路径中的节点进行排序。您可以创建一个对 0、1、3 的非连续索引起作用的二分搜索实现。也就是说,不是加或减 1,而是移动到子索引或父索引。不过,重点是您实际上不会使用二分搜索来查找节点的位置。提出的问题是假设性的。
  • 明白了,先生。谢谢! :)
【解决方案2】:

堆数组显然没有排序。

路径已排序,除了您要插入的最后一个节点。它是排序的,因为在最大堆中,任何节点都大于或等于它的子节点,并且由于路径是由子节点组成的,因此它们将按降序排列。在此设置中我们可以忽略的最后一个节点,因为我们知道它不合适。

所以问题要求您通过路径上的二进制搜索来找到要插入新节点的位置。路径的长度为 O(logN)。对于 N 个元素,二分搜索是 O(logN)。所以复杂度将是 O(loglogN)。

这不会导致正确的堆,它只会告诉您插入新节点的位置。您仍然必须沿着路径将每个节点移动到堆中更深的位置,这仍然是 O(logN)。

【讨论】:

  • 非常感谢,这不会导致正确的堆,它只会告诉您插入新节点的位置。您仍然必须沿着路径将每个节点移动到堆中更深的位置,这仍然是 O(logN)。 你的意思是,我必须调用 Max Heapify,对吗?
  • @Geeklovenerds 是的。
猜你喜欢
  • 2017-05-20
  • 2018-09-13
  • 2013-12-17
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 2020-02-10
相关资源
最近更新 更多