在本文中,我将比较线性搜索和二进制搜索算法。 您将看到每种算法的伪代码,以及示例和实现每种方法的逐步指南。
介绍
作为程序员,您想找到问题的最佳解决方案,以使您的代码不仅正确而且高效。 选择次优算法可能意味着更长的完成时间,增加的代码复杂度或使崩溃的程序更糟。
您可能已经使用搜索算法来查找数据集合中的项目。 JavaScript语言有多种方法,例如find
,可以在数组中定位项目。 但是,这些方法使用线性搜索。 线性搜索算法从列表的开头开始,并将每个元素与搜索值进行比较,直到找到它为止。
当元素较少时,这很好。 但是,当您搜索包含数千或数百万个元素的大型列表时,您需要一种更好的方式来查找项目。 这是您将使用二进制搜索的时间。
在本教程中,我将解释二进制搜索的工作原理以及如何在JavaScript中实现该算法。 首先,我们将回顾线性搜索算法。
线性搜寻
我们将首先说明如何在JavaScript中实现线性搜索。 我们将创建一个名为linearSearch
的函数,该函数接受一个整数或字符串值以及一个数组作为参数。 该函数将在数组中的每个元素中搜索该值,如果找到该值,则返回该值在数组中的位置。 如果该值不在数组中,则它将返回-1。 例如,调用linearSearch(1, [3, 4, 2, 1, 5])
将返回3,而调用linearSearch(0, [3, 4, 2, 1, 5])
将返回-1。
这是我们函数的一些伪代码:
Set found to false
Set position to −1
Set index to 0
while found is false and index < number of elements
if list[index] is equal to search value
Set found to true
Set position to index
else Add 1 to index
return position
线性搜索JavaScript实现
这是线性搜索算法JavaScript实现:
function linearSearch(value, list) {
let found = false;
let position = -1;
let index = 0;
while(!found && index < list.length) {
if(list[index] == value) {
found = true;
position = index;
} else {
index += 1;
}
}
return position;
}
重要的是要注意,线性搜索算法不需要使用排序列表。 而且,可以自定义算法以用于不同的场景,例如通过键搜索对象数组。 如果您的客户数据数组包含名字和姓氏的键,则可以测试该数组是否有一个具有指定名字的客户。 在这种情况下,您可以检查list[index].first
,而不是检查list[index]
是否等于我们的搜索值。
在上面的示例中,我在具有五个元素的数组上使用了linearSearch
函数。 在最坏的情况下,当搜索值不在列表中或不在列表末尾时,该函数将必须进行五次比较。 由于我们的数组很小,因此无需使用其他算法进行优化。 但是,超出某个点,使用线性搜索算法不再有效,也就是说,使用二进制搜索算法会更好。
二元搜寻
假设您正在玩数字猜谜游戏。 要求您猜测一个介于1到100之间的数字。如果您的数字太大或太小,都会得到提示。
您的策略是什么? 您会随机选择数字吗? 您会从1开始,然后从2开始,依此类推,直到猜对为止? 即使您有无限的猜测,您也想通过尽可能少的尝试做出正确的猜测。 因此,您可以从猜测50开始。如果数字较高,则可以猜测75。如果数字较低,则表示数字在50到75之间,您可以选择一个中间的数字。 您将继续这样直到到达正确的数字。 这类似于二进制搜索的工作方式。
与线性搜索不同,二进制搜索使用排序列表。 要搜索值,首先将值与列表的中间元素进行比较。 如果它们相等,则找到搜索值。 如果搜索值大于中间元素,则搜索数据的上半部分。 然后,将本节的中间元素与搜索值进行比较。 或者,如果该项小于中间元素,则搜索列表的下半部分并比较其中间值。 将该列表重复分成两半,直到找到该元素或没有其他要搜索的项目为止。
要在列表中搜索9:
1 2 3 4 5 6 7 8 9 10
我们首先找到中间元素。 这是位置Math.floor((first + last)/2)
处的元素,其中first
是第一个索引, last
是最后一个索引。 我们选择四舍五入,以便如果结果为分数,则变为整数。 该列表的中间元素为5。我们的搜索值9大于5,因此我们搜索列表:
6 7 8 9 10
这部分的中间元素是8。9大于8,所以我们搜索列表:
9 10
中间元素是9,因此我们可以在此处停止搜索。
这是一些表示上述用于二进制搜索的算法的伪代码:
Set first to 0
Set last to the last index in the list
Set found to false
Set position to −1
while found is false and first is less than or equal to last
Set middle to the index halfway between first and last
if list[middle] equals the desired value
Set found to true
Set position to middle
else if list[middle] is greater than the desired value
Set last to middle − 1
else
Set first to middle + 1
return position
二进制搜索JavaScript实现
现在,让我们用JavaScript编写二进制搜索算法!
我们将创建一个函数binarySearch
,该函数接受一个值和一个数组作为参数。 如果找到,它将返回列表中值所在位置的索引。 如果找不到该值,则返回-1。 这是我们用JavaScript编写的实现:
function binarySearch(value, list) {
let first = 0; //left endpoint
let last = list.length - 1; //right endpoint
let position = -1;
let found = false;
let middle;
while (found === false && first <= last) {
middle = Math.floor((first + last)/2);
if (list[middle] == value) {
found = true;
position = middle;
} else if (list[middle] > value) { //if in lower half
last = middle - 1;
} else { //in in upper half
first = middle + 1;
}
}
return position;
}
结论
在本教程中,我们看到了如何实现线性搜索和二进制搜索算法。 线性搜索算法更简单,不需要排序数组。 但是,与较大的数组一起使用时效率很低。 在最坏的情况下,该算法必须搜索所有进行n次比较的元素(其中n是元素数)。
另一方面,二进制搜索算法要求您首先对数组进行排序,并且实现起来更加复杂。 但是,即使考虑分拣成本,它也更有效。 例如,具有10个元素的数组最多可以对二进制搜索进行4个比较,而对于线性搜索最多可以进行10个比较-并不是很大的改进。 但是,对于具有1,000,000个元素的数组,二进制搜索中最坏的情况是只有20个比较。 与线性搜索相比,这是一个巨大的进步!
知道如何使用二进制搜索不仅是面试问题的练习内容。 这是一项实用技能,可以使您的代码更高效地工作。
翻译自: https://code.tutsplus.com/tutorials/the-binary-search-algorithm-in-javascript--cms-30003