【问题标题】:Counting the number of Nodes in Binary Tree O(logn)^2计算二叉树中的节点数 O(logn)^2
【发布时间】:2020-08-25 09:47:41
【问题描述】:

我有一个问题,我需要在
O((log(n))^2) 的时间复杂度中找到完整树中的节点数,例如(n 的日志)^2,我的目标是
找到h,即h= log n(树的高度,总是向左移动,因为它是一棵完整的树)然后来到h-1的每个节点并检查它是否有一个正确的节点,如果有,那么它必须有一个左节点(因为完整的树),如果它没有然后检查它是否有一个左节点,就像计算节点的数量一样。

问题是我认为是O(n),因为h = log(n)和这个高度的节点数是2^(h-1),所以整个过程是O(n)而不是O( (log n)^2)..


的输出
是 12,因为它有 12 个节点,时间复杂度为 O((log n)^2)

非常感谢您的帮助!谢谢。

【问题讨论】:

  • 您可以在最后一行中的项目停止的地方执行二分搜索,然后计算节点数。
  • 也许你可以将它与二分搜索结合起来(你知道它是一棵完整的树)......
  • @WillemVanOnsem 是否对 h-1 行中的每个节点进行二进制搜索? (不是最后一行)?
  • @StackOMeow:您只需在h-1 行的哪个节点处进行二分搜索,这些节点不再有两个子子节点。
  • @StackOMeow:完全正确。

标签: algorithm binary-tree big-o


【解决方案1】:

首先,通过遍历left 指针计算到最左边叶子的距离。然后对right 指针执行相同的操作。如果两个数字都是n,那么你就有了一个有 2^n - 1 个节点的完美树。

否则,它们不相等。然后第一个计数是某个数字n+1,第二个计数是n。我们需要探测 - 正如其他人所说的那样使用二分搜索 - 完整的n-deep 节点层(将根计算为第 1 层)以找到最左边的具有 0 个或 1 个子节点的节点。有 2^(n-1) 个节点要探测。在示例中,n=3,因此我们正在探测 4 个节点。

我们可以通过考虑数字 0..2^(n-1) - 1 中的位来探测该层。在示例中,这是 0..3(即 n-2 位)。在从根到叶的遍历中,0 位表示“向左走”。 1 表示“向右走”。出于下面讨论的原因,您希望使用从根到叶的从最高到最低的位(在示例中,位 1,0)。不难看出,使用 0..2^(n-1) - 1 作为路径遍历“指令”,您将从左到右到达该层中的每个顶点。例如,2 有 10 位。这意味着从根开始,向右然后向左,这会将您带到 F。

但是你当然不想搜索 n 层中的每个顶点,因为这会使你的搜索 O(n)。相反,使用二进制搜索。首先尝试 [0..2^(n-1) - 1] 中点的“指令”。如果您找到 2 个孩子,则将搜索括号减少到大于中点的值。如果您找到 0 个孩子,则价值较小。以这种方式继续,直到找到具有 1 个子节点的节点或括号大小为 1 并且有 0 个子节点。后者意味着您在图层中找到了最左边的节点,没有子节点。

现在我们可以很容易地找到孩子的总数。树的向下到第 n 层的部分有 2^(n-1) - 1 个节点,将您带到最终搜索节点的“指令”告诉您在第 n+1 层中有多少个节点。这些一起告诉你最终的答案。我会让你弄清楚最后的细节。

【讨论】:

    【解决方案2】:

    正如迈克尔告诉你的,你必须以某种方式在你的问题中应用二进制搜索。 所以最简单的方法就是通过这个算法:

    1. 首先,正如您所说,我们必须找到一棵树的高度,为此,我们只需直奔最左边的节点即可;
    2. 既然我们知道树的高度 H,现在我们可以应用二分查找:

    3. 我将描述根的算法,对于每个下一个节点都是相同的:

      每次我们搜索右子树的最左叶。

      因此,如果在高度 H 上有一个叶子,如图所示,则与右孩子重复过程(找到树的右子树的最左边的叶子,其中“根”是节点 C)。

      如果没有叶子,则对根的左孩子重复相同的过程。

    正如我们所见,每次我们将问题减少 2 倍。 所以复杂度是 H *(搜索量)= log n * log n

    【讨论】:

    • 这个算法只返回最后一层(高度H)的节点数对吧?因为我们知道节点数 = 节点高度 H + 2^(h-1) -1
    • 是的,你是对的。我们知道高度上的全部节点数量:H - 1,正如您所写,所以我们必须计算最后一层的节点数量。
    • 我很困惑,关于算法,假设我们在 F 它有一个左孩子, L 而不是右孩子,所以我们可以在这里停下来,而不是移动到左子树就像你的算法建议的那样,不是吗?
    • 这是品味问题。在我看来,当我们处于叶级别时更容易停止,所以我们只需要检查左右节点是否为空,我们就在这里。但同样,何时停止取决于您。
    • 但是在你的算法中你说如果我们没有高度为 H 的叶子那么我们对左子树做同样的事情但它不会永远结束,因为假设你检查:L 是高度 H 上的叶子:很好,然后对右子树做同样的事情 - G 是高度 H 上的叶子吗?不,然后去 A so-node J 的左子树的最左边的叶子,但是,为什么?如果我们发现G没有孩子而F只有一个,那么E和D当然会有孩子..算法的stop if语句是什么,我们什么时候停止?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多