为什么这个二叉树搜索比插入花费的时间长得多?

时间:2017-01-18 16:54:14

标签: algorithm go time-complexity binary-tree

我正在尝试学习/理解一些基本算法,今天我决定在Go中编写一个二叉树。这就是结构的样子:

type Node struct {
  Value int
  Left  *Node
  Right *Node
}

这是检查树是否包含int的函数:

func (tree *Node) Contains(val int) bool {
  if val == tree.Value {
    return true
  } else if val > tree.Value {
    if tree.Right != nil {
      return tree.Right.Contains(val)
    } else {
      return false
    }
  } else if val < tree.Value {
    if tree.Left != nil {
      return tree.Left.Contains(val)
    } else {
      return false
    }
  } else { // huh
    return false
  }
}

我编写了一个测试函数来测试树上不同操作的时间。我的Insert()函数 34ms 需要插入100,000个随机整数,我的Contains()函数 33ms 检查树是否包含100,000个随机整数。如果我将随机整数的数量增加到1,000,000,则需要运行Insert()函数 34ms ,但我的Contains()函数突然需要 321ms 跑。

为什么Contains()的运行时间会急剧增加,而Insert()几乎保持不变?

1 个答案:

答案 0 :(得分:1)

Insert函数应该定期重新平衡树,因为不平衡的树可能会导致非常不均匀的遍历时间。因此,Insert 通常要比Contains慢。

如果你的Insert函数没有重新平衡树,那么任何给定函数所需的时间都会变成O(n)最坏情况而不是O(log n)并且相当不可预测。

此外,在谈论O(...)时间复杂度时,我们通常会谈论最坏情况行为。如果你对单个调用进行计时,那么任何给定的调用可能比最坏的情况花费更少的时间 - 例如,Contains查找恰好是root的节点将立即返回,无论大小如何。< / p>