【问题标题】:Complexities of binary tree traversals二叉树遍历的复杂性
【发布时间】:2021-07-29 11:23:26
【问题描述】:

数据结构中二叉树的中序、后序和前序遍历的时间复杂度是多少?是 O(n) 还是 O(log n) 还是 O(n^2)?

【问题讨论】:

  • 哪些数据结构?树?什么类型的树?
  • 这个问题属于cstheory.stackexchange.com
  • @CommanderZ - 让我们不要开始分裂头发。

标签: time-complexity


【解决方案1】:

O(n),因为你遍历每个节点一次。或者更确切地说 - 您为每个节点所做的工作量是恒定的(不依赖于其余节点)。

【讨论】:

  • 如果我在递归中这样做,postorder 的复杂之处是什么?
  • @Software_t - 这有什么关系?
【解决方案2】:

对于任何订单,遍历都是 O(n) - 因为您要访问每个节点一次。如果树具有某种组织架构(即二叉搜索树),则查找可以小于 O(n)。

【讨论】:

    【解决方案3】:

    O(n),我会说。 我正在做一棵平衡的树,适用于所有的树。 假设你使用递归,

    T(n) = 2*T(n/2) + 1 ----------> (1)

    T(n/2) 用于左子树,T(n/2) 用于右子树,'1' 用于验证基本情况。

    在简化 (1) 时,您可以证明遍历(中序或前序或后序)的顺序为 O(n)。

    【讨论】:

    • 这个答案对我来说似乎不正确,因为您假设树在左侧和右侧均匀地分成两半。
    【解决方案4】:

    有序、前序和后序遍历是深度优先遍历。

    对于 Graph,深度优先遍历的复杂度为 O(n + m),其中 n 是节点数,m 是边数。

    由于二叉树也是一个图,这里同样适用。 每个深度优先遍历的复杂度都是 O(n+m)。

    由于在二叉树的情况下,可以源自一个节点的边数限制为 2,因此二叉树中总边的最大数量为 n-1,其中 n 是节点的总数。

    那么复杂度就变成了O(n + n-1),也就是O(n)。

    【讨论】:

      【解决方案5】:

      简介

      嗨

      我今天在课堂上被问到这个问题,这是一个很好的问题!我将在这里进行解释,并希望在错误的地方对我更正式的答案进行审查或更正。 :)

      以前的答案

      @Assaf 的观察也是正确的,因为二叉树遍历递归地遍历每个节点一次。

      但是!由于它是一种递归算法,因此您通常必须使用更高级的方法来分析运行时性能。在处理顺序算法或使用 for 循环的算法时,使用求和通常就足够了。所以,下面是对这个分析的更详细的解释,供好奇的人参考。

      复发

      如前所述,

      T(n) = 2*T(n/2) + 1

      其中 T(n) 是在您的遍历算法中执行的操作数(按顺序、前序或后序都没有区别。

      重复的解释

      有两个T(n),因为中序、前序和后序遍历都在左右子节点上调用自己。因此,将每个递归调用视为一个T(n)。换句话说,**左 T(n/2) + 右 T(n/2) = 2 T(n/2) **。 “1”来自函数内的任何其他恒定时间操作,例如打印节点值等。 (老实说,它可能是 1 或任何常数,并且渐近运行时仍然计算为相同的值。解释如下。)。

      分析

      这种递归实际上可以使用大师定理使用大 theta 来分析。所以,我会在这里应用它。

      T(n) = 2*T(n/2) + 常数

      其中常数是一些常数(可以是 1 或任何其他常数)。

      使用Masters' Theorem,我们有T(n) = a*T(n/b) + f(n)。

      所以,a=2, b=2, f(n) = constant 因为f(n) = n^c = 1,那么有c = 0 因为 f(n) 是一个常数。

      从这里,我们可以看到 a = 2 和 b^c = 2 ^0 = 1。所以,a>b^c 或 2>2^0。所以,c 或 0

      从这里我们有 T(n) = BigTheta(n^{logb(a)}) = BigTheta(n^1) = BigTheta(n)

      如果您不熟悉 BigTheta(n),它与 ​​O(n)“相似”(请耐心等待 :)),但它是“更严格的界限”或更严格的近似运行时。因此,BigTheta(n) 是最坏情况 O(n) 和最佳情况 BigOmega(n) 运行时。

      我希望这会有所帮助。保重。

      【讨论】:

        【解决方案6】:

        T(n) = 2T(n/2)+ c

        T(n/2) = 2T(n/4) + c => T(n) = 4T(n/4) + 2c + c

        类似地 T(n) = 8T(n/8) + 4c+ 2c + c

        ....

        ....

        最后一步... T(n) = nT(1) + c(2从0到h(树的高度)的幂的和)

        所以复杂度是 O(2^(h+1) -1)

        但是 h = log(n)

        所以,O(2n - 1) = O(n)

        【讨论】:

          【解决方案7】:

          考虑一棵有 3 个节点的倾斜二叉树,分别为 7、3、2。对于像搜索 2 这样的任何操作,我们必须遍历 3 个节点,删除 2 也必须遍历 3 个节点,插入 1 也必须遍历,我们必须遍历 3 个节点。因此,二叉树的最坏情况复杂度为 O(n)。

          【讨论】:

            【解决方案8】:

            二叉树的深度优先遍历的顺序为 O(n)。

            Algo -- <b>
                PreOrderTrav():-----------------T(n)<b>
                if root is null---------------O(1)<b>
                  return null-----------------O(1)<b>
                else:-------------------------O(1)<b>
                  print(root)-----------------O(1)<b>
                  PreOrderTrav(root.left)-----T(n/2)<b>
                  PreOrderTrav(root.right)----T(n/2)<b>
            

            如果算法的时间复杂度是 T(n),那么它可以写成 T(n) = 2*T(n/2) + O(1)。 如果我们应用反向替换,我们将得到 T(n) = O(n)。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-02-16
              • 2012-01-01
              • 2022-11-11
              • 2017-11-28
              • 1970-01-01
              • 2021-11-20
              相关资源
              最近更新 更多