【问题标题】:Why would I prefer binary search over linear search in an unsorted array?为什么我更喜欢二进制搜索而不是未排序数组中的线性搜索?
【发布时间】:2020-05-19 16:46:36
【问题描述】:

我一直在 Coursera 上参加 DSA 课程,本周我学习了搜索算法。而二分查找的复杂度(O(logn))优于线性查找的复杂度(O(n))。但是,考虑到首先对数组进行排序需要 nlogn 工作,我为什么要在未排序的数组中使用它。

如果只在数组已经排序的地方使用二分查找,那为什么要经常比较这两种算法,因为显然它们有不同的用例。

【问题讨论】:

  • 因为经过一个排序步骤O(n log n),您可以进行数千个查询。这基本上就是数据库索引的用途。请注意,将元素添加到 AVL 树需要 O(log n).
  • @WillemVanOnsem:我相信当查询数 >n 时最适用(承认 >n 在算法复杂性方面是模糊定义的)
  • @MooingDuck:从查询数量大于 O(log n) 的那一刻起,人们就期待性能提升。

标签: algorithm sorting binary-search linear-search


【解决方案1】:

考虑到首先对数组进行排序需要 O(n log n) 个工作,我是否会在未排序的数组中使用它。

通常对同一数据结构执行多个查询。确实,以数据库为例。与添加记录相比,使用给定主键获取记录的频率更高,这是有道理的。这是有道理的,因为如果查询的数量少于插入的数量,那么我们插入的数据永远不会被检索到,因此这些是“无用的”。

此外,对元素列表进行排序,或构建元素的二叉树确实需要 O(n log n)。但是更新二叉搜索树,例如AVL tree [wiki] 需要O(log n)。因此,如果您通过添加一个元素、删除一个元素、更新一个元素等稍微更改元素的集合。它需要 O(log n) 来更改数据结构,并且您继续维护O(log n) 查找。

对未排序的数据使用线性搜索,在少量查询中确实会优于排序和二分搜索。从查询数量变大的那一刻起,线性搜索算法的性能将优于二分搜索算法。

【讨论】:

  • 谢谢威廉。你的解释很实用。
【解决方案2】:

Willem Van Onsem 的回答很好地描述了将在同一个数组上进行许多查询的情况,因此值得花 O(n log n) 时间首先对数组进行排序。我的回答没有直接解决“未排序的数组”,但是有一个常见的误解,即数组要么 未排序,要么 排序,我认为值得解决这个问题误解,以防它对任何读者有所帮助。

需要明确的是,我不认为您有这种特殊的误解。但我确实认为一些有这种误解的人会阅读您的问题及其答案。


“排序”这个词有点误导。由于“sorted”是过去式动词,因此听起来像是使用了排序算法来整理数据。但是计算机科学家使用“排序”这个词的方式,它只是表示数组有序的,而不是暗示它以前不是有序的。

所以当我们说二进制搜索只能用于“排序数组”时,这并不意味着需要 O(n log n) 时间才能使数组“排序”。大量数据自然井然有序,无需进行任何工作对其进行排序。几个例子:

  • 假设我有一个未排序的数字数组,我想构建一个prefix sum array,其中包含从原始数组开头开始的累积和。如果原始数组中没有负数,那么累积和自然是升序排列。
  • 假设我有一个包含一些特殊元素的序列,并且我想执行查询,在给定索引的情况下,查询会找到该索引之后的第一个特殊元素。列出特殊元素出现的顺序中的索引列表会有所帮助;查找这些索引的自然方法是按升序查找它们。
  • 假设我想要一个由第一个n 素数组成的数组,或者所有小于或等于n 的素数。几乎任何解决这两个问题的算法都会按升序生成素数。

所以在很多情况下,我们可以应用二分查找,而不必花费 O(n log n) 时间来对需要查找的序列进行排序。

【讨论】:

  • 感谢您的解释。它将帮助读者获得更多有关问题的背景信息。
猜你喜欢
  • 1970-01-01
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 2022-10-02
  • 2014-11-05
  • 1970-01-01
  • 2020-09-17
相关资源
最近更新 更多