JavaScript 中的线性搜索和二进制搜索

2025-05-27

JavaScript 中的线性搜索和二进制搜索

这周我开始阅读《Grokking's Algorithms》,这是一本面向程序员和其他好奇人士的图文并茂的指南。目前为止,这本书读起来非常棒——充满了实用的例子,并配有有趣的插图,以通俗易懂的方式解释了技术概念。书中的代码示例是用 Python 编写的。我主要是一名 JavaScript 开发人员,所以我想先学习一下这本书,然后向大家展示我的 JavaScript 代码。

搜索数组

您正在列表中搜索某个东西。您不确定它是否真的在列表中,但如果在,您想知道它在哪里。在这种情况下,我们有一个彩虹,我们正在寻找一种特定的颜色。

var rainbow = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];
Enter fullscreen mode Exit fullscreen mode

简单的 坏的直线导轨

您可能会想,“简单!我只需循环遍历数组的每个元素并返回匹配项!”这有效,称为线性搜索。

function linearSearch(arr, elToFind) {
  for (var i=0; i<arr.length; i++) {
    if (arr[i] == elToFind) {
      return i;
    }
  } return null;
}

linearSearch(rainbow, "green"); // returns 3
linearSearch(rainbow, "white"); // returns null
Enter fullscreen mode Exit fullscreen mode

但是,(虽然这个数组的大小取决于你的数据集的大小)这里面存在性能方面的权衡。你必须循环遍历每个元素才能发现你的元素不在数组中。当我们只讨论 7 种颜色时,这没什么,但如果我们要遍历一个包含数千或数百万条记录的数组呢?还是算了吧。

二分查找

二分查找以已排序的数组为输入,查找特定元素。如果该元素存在于数组中,则返回元素的索引;否则返回 null。由于数组已经排序,因此查找可以将目标元素与数组中间的元素进行比较,从而一次消除一半的搜索范围。可以将其想象成一场“冷热”游戏。

替代文本

使用二分查找重试彩虹示例

你我都理解前面提到的彩虹的 ROY G. BIV 排序,但你的浏览器可不是幼儿园出身。为了对彩虹进行二分查找,需要先按字母顺序排序。幸运的是,我们有 JavaScript 内置的数组排序方法。

var rainbow = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];
var sortedRainbow = rainbow.sort(); 
// returns ["blue", "green", "indigo", "orange", "red", "violet", "yellow"];
Enter fullscreen mode Exit fullscreen mode

太棒了!现在我们有了可以传递给二分查找的东西。

function binarySearch(sortedArray, elToFind) {
  var lowIndex = 0;
  var highIndex = sortedArray.length - 1;
  while (lowIndex <= highIndex) {
    var midIndex = Math.floor((lowIndex + highIndex) / 2);
    if (sortedArray[midIndex] == elToFind) {
      return midIndex;
    } else if (sortedArray[midIndex] < elToFind) {
      lowIndex = midIndex + 1;
    } else {
      highIndex = midIndex - 1;
    }
  } return null;
}

var sortedRainbow = ["blue", "green", "indigo", "orange", "red", "violet", "yellow"];
binarySearch(sortedRainbow, "green"); // returns 1
binarySearch(sortedRainbow, "white") // returns null
Enter fullscreen mode Exit fullscreen mode

好了,说了这么多。或许你是个搜索高手,完全理解了。让我们逐行进行二分查找。

  • binarySearch函数接受一个sortedArray和一个您要搜索的元素 ( elToFind )。

    • 在搜索过程中,您将跟踪搜索的范围,其起始低索引为 0,起始高索引为排序数组中元素的数量。搜索开始时,范围将覆盖整个数组。
    • while循环一直执行,直到搜索范围缩小到一个元素

      • 找到lowIndexhighIndex之间元素的索引,计算这两个值的平均值(注意:使用 Math.floor 将此值向下舍入,因为midIndex必须是整数)
      • 如果找到了元素,则返回索引
      • 如果当前元素小于(按字母顺序排列)要搜索的元素,则将lowIndex增加到比midIndex大一
      • 如果当前元素大于(按字母顺序排列)要搜索的元素,则将highIndex减小为比midIndex小一
    • 如果元素在数组中不存在,则返回 null

下一步

既然我们已经了解了两种搜索方法(线性和二元),我们需要一种方法来衡量它们的性能。在我的下一篇文章中,我将探讨对数(回归代数2)和大O符号。敬请期待!

文章来源:https://dev.to/stephjs/linear-and-binary-search-in-javascript-4b7h
PREV
如何成为卓越?只要不断保持优秀
NEXT
完整的 Windows Web 开发人员设置指南