二分搜索与二叉搜索树

joh*_*ohn 26 arrays algorithm binary-tree time-complexity data-structures

二进制搜索树对具有二分搜索的排序数组有什么好处?只是通过数学分析我没有看到差异,所以我假设低级实现开销必须存在差异.平均病例运行时间的分析如下所示.

使用二进制搜索
搜索的排序数组:O(log(n))
插入:O(log(n))(我们运行二进制搜索以查找插入元素的位置)
删除:O(log(n))(我们运行二进制搜索找到要删除的元素)

二进制搜索树
搜索:O(log(n))
插入:O(log(n))
删除:O(log(n))

对于上面列出的操作,二进制搜索树具有最坏的O(n)情况(如果树不平衡),所以这看起来实际上比使用二进制搜索的排序数组更差.

另外,我不假设我们必须预先对数组进行排序(这将花费O(nlog(n)),我们将逐个插入元素到数组中,就像我们对二叉树所做的那样.唯一的好处BST我可以看到它支持其他类型的遍历,如inorder,preorder,postorder.

Bli*_*ndy 29

您的分析是错误的,对于已排序的数组,插入和删除都是O(n),因为您必须物理移动数据以为插入腾出空间或压缩它以掩盖已删除的项目.

哦,完全不平衡的二叉搜索树的最坏情况是O(n),而不是O(logn).

  • 不过,从中得出结论时要小心,因为在 RAM 中移动内存块是最优化的操作之一(在现代计算机中)。 (2认同)
  • 对于适合缓存的足够小的数组来说,它有点作用。 (2认同)

Meh*_*dad 7

查询任何一个都没有太大的好处.

但是,当您一次添加一个元素时,构造排序树比构建排序数组要快得多.所以当你完成时将它转换为数组是没有意义的.

  • 如果您不必支持插​​入或删除(例如,您预先构建一个数据集),则排序数组将比二进制搜索树更快地显示一个非常显着的常数因子.你的数组没有任何空间开销,当你的数据是紧凑的并且你不必追逐指针时,你的缓存可以更好地工作. (16认同)
  • Mehrdad,除了你说的不是你说的.你说无论是一个还是另一个都没有任何好处,没有任何一点可以转换成一个数组,而Rob Neuhaus说的恰恰相反:一个排序的数组会对树有一个很大的恒定因子优势.罗布是对的. (7认同)
  • 您再次失去了重点。我和Rob Neuhaus都没有评论您要求的第二部分,只是第一部分,即“查询任何一个都没有太大好处”。查询排序数组有一个常数因数的好处。您的相反说法是错误的。我同意您的第二项主张,但想更正您的第一项主张。您是否不同意查询排序数组会带来常量因素的好处? (2认同)
  • 我当然看到了整个问题。该问题表明对“低级实施开销”感兴趣。我同意,对于查询而言,这只是一个常数。问题在于罗布所说的“相当重要的常数”是否与“差别不大”相同。我不同意当我们已经同意big-O相同时,应该将“相当重要的常数因子”归类为“没有太大的好处”。在实际程序中,“相当重要的常数因子”是相当大的好处。他们是两个不同的主张。 (2认同)