【问题标题】:Where is binary search used in practice?二进制搜索在实践中在哪里使用?
【发布时间】:2010-10-07 02:40:49
【问题描述】:

每个程序员都被教导二进制搜索是搜索有序数据列表的一种很好、快速的方法。使用二分搜索的玩具教科书有很多例子,但在实际编程中呢:二分搜索在实际程序中实际使用在哪里?

【问题讨论】:

  • 实践中用圆钉塞圆孔在哪里?
  • 因为我觉得在最重要的答案中没有得到足够的强调,所以我想澄清一下,当您的数据被 排序 时会使用二进制搜索。我最近的例子是检查给定单词是否在我知道要排序的单词列表中(因为我自己在程序的前面对其进行了排序)。如果您的数据未排序或无法排序,则您无法信任二分搜索的结果。
  • 如果你现在问这个问题,它会因为含糊而被关闭。这太糟糕了——这是一个很好的问题!

标签: algorithm binary-search


【解决方案1】:

一个例子是 stl 集。底层数据结构是平衡的二叉搜索树,由于二叉搜索,支持O(log n)的查找、插入和删除。

另一个例子是在对数时间内运行的整数除法算法。

【讨论】:

  • 两者都不是二分搜索的例子。
  • 在平衡二叉搜索树中查找重复消除了排序集合的剩余搜索空间的一半。那就是二分查找。要在不使用“/”的情况下计算 a/b,有一个循环重复地将 int 的值加倍,直到它稍微太大。我再次进行二进制搜索。
  • @antii.huima,嗯...是的,他们都是。
  • 其实“二分查找”通常是在一个有序数组上完成的。它是一种算法。 “二叉搜索树”是一种表示二叉搜索的数据结构。
【解决方案2】:

二分搜索好又快的方法!

在 STL 和 .NET 框架等出现之前,您经常会遇到需要推出自己的自定义集合类的情况。每当排序数组成为存储数据的可行位置时,二进制搜索就是在该数组中定位条目的方法。

我很确定二进制搜索在今天也得到了广泛使用,尽管为了您的方便,它由库“在后台”处理。

【讨论】:

    【解决方案3】:

    如果您要在数组中查找一组元素,您可以线性搜索每个元素,也可以对数组进行排序,然后使用具有相同比较谓词的二分查找。后者要快得多。

    【讨论】:

    • 不正确,除非符合以下条件:如果您的查找次数证明对输入进行排序所需的 O (n log n) 时间是合理的,则可能会更快。
    【解决方案4】:

    我已经在 BTree 实现中实现了二进制搜索。

    BTree 搜索算法用于查找下一个要读取的节点块,但在 4K 块本身(包含基于密钥大小的多个密钥)内,二进制搜索用于查找记录号(例如叶节点)或下一个块(对于非叶节点)。

    与顺序搜索相比,速度快得惊人,因为就像平衡二叉树一样,每次检查都会删除一半的剩余搜索空间。

    【讨论】:

      【解决方案5】:

      我们仍然在代码中大量使用它来每秒搜索数千次数千次 ACLS。它很有用,因为 ACL 一旦从文件中进入,它们就是静态的,并且我们可能会在启动时添加阵列时承受增长阵列的代价。运行后速度也非常快。

      当您最多可以在 7 次比较/跳转中搜索一个 255 个元素的数组(8 次比较/跳转中 511 次,9 次中 1023 次等)时,您会发现二分查找的速度几乎与您所能获得的一样快。

      【讨论】:

      • 对于外行来说,什么是 ACLS?我假设您不是指高级心脏生命支持。
      【解决方案6】:

      在其他地方,我有一个解释器,其中包含一个命令名称表和一个指向解释该命令的函数的指针。大约有 60 个命令。使用线性搜索不会非常繁重 - 但我使用二进制搜索。

      【讨论】:

        【解决方案7】:

        每个程序员在调试时都需要知道如何使用二分查找。

        如果您有一个程序,并且您知道某个错误在某个特定点是可见的 在程序执行过程中,您可以使用二分搜索来精确定位 实际发生的地方。这可能比单步执行要快得多 大部分代码。

        【讨论】:

        • 你能解释一下吗?我想我明白你的意思,但我不同意人类在发现错误时应用二进制搜索。
        • 我没有说它总是被使用,甚至它必须总是被使用。我说这是必备技能。
        • 问题是where is binary search actually used in real-life "programs",而不是where is binary search actually used in real-life
        • @Polaris878 虽然最初的答案与现实生活中的程序无关,但git-scm.com/docs/git-bisect 是人​​类应用二进制搜索的一个例子
        【解决方案8】:

        二分搜索无处不在。从任何语言库(Java、.NET、C++ STL 等)中获取任何排序的集合,它们都将使用(或可以选择使用)二进制搜索来查找值。虽然您必须很少实施它,但您仍然必须了解它背后的原理才能利用它。

        【讨论】:

          【解决方案9】:

          我曾经为一个在图形中显示二维数据的 GUI 控件实现了它(甚至不知道这确实是二进制搜索)。用鼠标单击应将数据光标设置到具有最接近 x 值的点。当处理大量点时(几个 1000,这是 x86 刚刚开始超过 100 MHz CPU 频率的时候),这并不是真正可用的交互式 - 我从一开始就进行线性搜索。经过一番思考,我突然想到我可以分而治之的方式来解决这个问题。我花了一些时间让它在所有边缘情况下都能正常工作。

          过了一段时间我才知道这确实是一个基础的 CS 算法……

          【讨论】:

            【解决方案10】:

            用于测量数字时序或模拟电平的半导体测试程序广泛使用二进制搜索。来自 Advantest、Teradyne、Verigy 等的自动测试设备 (ATE) 可以被认为是真值表爆破器,应用输入逻辑并验证数字部件的输出状态。

            考虑一个简单的门,输入逻辑在每个周期的时间 ​​= 0 处发生变化,并在输入逻辑发生变化后转换 X ns。如果在 T=X 之前选通输出,则逻辑与预期值不匹配。选通晚于时间 T=X,并且逻辑与预期值匹配。二进制搜索用于查找逻辑不匹配的最新值与它匹配的最早部分之间的阈值。(Teradyne FLEX 系统将时序解析为 39pS 分辨率,其他测试仪具有可比性)。这是一种测量过渡时间的简单方法。相同的技术可用于求解建立时间、保持时间、可操作电源电平、电源与延迟等。

            任何类型的微处理器、存储器、FPGA、逻辑和许多模拟混合信号电路都在测试和表征中使用二进制搜索。

            --麦克

            【讨论】:

              【解决方案11】:

              二分查找可用于快速访问有序数据当内存空间紧张时。假设您想将一组 100.000 个 32 位整数存储在一个可搜索的有序数据结构中,但您不会经常更改该集合。您可以轻松地将整数存储在 400.000 字节的排序数组中,并且可以使用二进制搜索快速访问它。但是如果你把它们放在例如进入 B-tree、RB-tree 或任何“更动态”的数据结构,您开始产生内存开销。为了说明,将整数存储在具有左子和右子指针的任何类型的树中都会消耗至少 1.200.000 字节的内存(假设 32 位内存架构)。当然,您可以进行一些优化,但一般情况下就是这样。

              因为更新有序数组(插入或删除)非常慢,所以当数组经常变化时,二分查找就没有用了。

              这里有一些我使用二分搜索的实际例子:

              • 在案例标签是单个整数的虚拟机中实现“switch() ... case:”构造。如果您有 100 个案例,您可以使用二分搜索在 6 到 7 个步骤中找到正确的条目,其中条件分支序列平均需要进行 50 次比较。
              • 使用后缀数组进行快速子字符串查找,其中包含按字典顺序排列的可搜索字符串集的所有后缀(我想节省内存并保持实现简单)
              • 寻找方程的数值解(当您很懒且不介意实现牛顿法时)

              【讨论】:

              • 关于switch/case:除非case非常稀疏,否则编译器会建跳转表。
              • 我只是想知道您是如何实现开关盒的。如果您可以分享实现,那就太好了
              【解决方案12】:

              寻找方程的根可能是您想要使用二进制搜索等非常简单的算法完成的非常简单的事情之一。

              【讨论】:

                【解决方案13】:

                Delphi 使用在排序后的 TStringList 中搜索字符串时可以享受二分查找。

                【讨论】:

                  【解决方案14】:

                  我有一个程序迭代一个集合来执行一些计算。我认为这是低效的,所以我对集合进行了排序,然后使用单个二进制搜索来查找感兴趣的项目。我退回了这个项目及其匹配的邻居。我实际上过滤了集合。

                  这样做实际上比迭代整个集合并找出匹配项要慢。

                  我知道排序和搜索性能最终会赶上迭代,所以我继续向集合中添加项目。它收集了大约 600 个对象,直到速度相同。 1000 个对象具有明显的性能优势。

                  我还会考虑您正在使用的数据类型、重复和传播。这将对排序和搜索产生影响。

                  我的答案是尝试这两种方法并计时。

                  【讨论】:

                    【解决方案15】:

                    我相信 .NET SortedDictionary 在幕后使用二叉树(很像 STL 映射)...所以使用二叉搜索来访问 SortedDictionary 中的元素

                    【讨论】:

                      【解决方案16】:

                      Python 的list.sort() 方法使用Timsort,它(AFAIK)使用二进制搜索来定位元素的位置。

                      【讨论】:

                        【解决方案17】:

                        嗯,binary search 现在用于 99% 的 3D 游戏和应用程序。空间被划分为树形结构,并使用二分搜索根据 3D 位置和相机检索要显示的细分。

                        它的第一个最伟大的展示是 Doom。二叉树和相关的搜索增强了渲染效果。

                        【讨论】:

                          【解决方案18】:

                          二分搜索提供了许多现成的地图/字典实现不具备的功能:查找非精确匹配项。

                          例如,我使用二进制搜索来实现基于 GPS 日志的照片地理标记:将所有 GPS 航点放入按时间戳排序的数组中,并使用二进制搜索来识别时间上最接近每张照片时间戳的航点.

                          【讨论】:

                            【解决方案19】:

                            这是hg bisect的基础

                            【讨论】:

                              【解决方案20】:

                              二进制排序在将字体调整为文本框尺寸不变的文本大小时很有用

                              【讨论】:

                                【解决方案21】:

                                二进制搜索可用于使用 Git 进行调试。它叫做git bisect

                                【讨论】:

                                  【解决方案22】:

                                  通过动手示例回答您的问题。

                                  在 R 编程语言中有一个包data.table。它从 C 实现的、短语法、高性能的数据转换扩展中得知。它使用二进制搜索。即使没有二分搜索,它的扩展性也比竞争对手好。
                                  您可以在项目 wiki grouping 2E9 中找到基准 vs python pandas 和 vs R dplyr - 随机顺序数据。
                                  还有很好的基准 vs 数据库 vs 大数据 benchm-databases

                                  在最近的 data.table 版本 (1.9.6) 中,二进制搜索得到了扩展,现在可以用作任何原子列的索引。

                                  我刚刚找到了一个很好的总结,我完全同意 - see

                                  任何进行 R 比较的人都应该使用 data.table 而不是 data.frame。基准测试更是如此。 data.table 是我职业生涯中发现的最好的数据结构/查询语言。它在 R 世界以及所有以数据为中心的语言中都处于领先地位。

                                  所以是的,二分搜索正在被使用,多亏了它,世界变得更好了。

                                  【讨论】:

                                    猜你喜欢
                                    • 2013-06-01
                                    • 2016-11-10
                                    • 2013-03-31
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 2022-01-08
                                    相关资源
                                    最近更新 更多