线性搜索和二进制搜索有什么区别?

时间:2009-03-31 06:21:12

标签: algorithm search binary-search linear

线性搜索和二进制搜索有什么区别?

11 个答案:

答案 0 :(得分:109)

linear search向下查看列表,一次查看一个项目,而不跳转。在复杂性方面,这是一个O(n)搜索 - 搜索列表所用的时间会以与列表相同的速率变大。

当您从排序列表的中间开始时,binary search是查看是否大于或小于您要查找的值,这将确定该值是在第一个还是后半个的清单。跳到子列表的中间位置,然后再次进行比较等。这几乎就是人类通常在字典中查找单词的方式(尽管我们使用更好的启发式方法,显然 - 如果你正在寻找“猫”,你不会从“M”开始)。在复杂性方面,这是一个O(log n)搜索 - 搜索操作的数量比列表的增长速度慢,因为每次操作都会使搜索空间减半。

例如,假设您在A-Z字母列表中寻找U(索引0-25;我们正在寻找索引20处的值)。

线性搜索会问:

  

list[0] == 'U'?第
     list[1] == 'U'?第
     list[2] == 'U'?第
     list[3] == 'U'?第
     list[4] == 'U'?第
     list[5] == 'U'?第
     ...      list[20] == 'U'?是。结束。

二进制搜索会询问:

  

list[12]('M')与'U'进行比较:较小,请继续查看。 (范围= 13-25)
     将list[19]('T')与'U'进行比较:较小,请进一步查看。 (范围= 20-25)
     比较list[22]('W')和'U':更大,看得更早。 (范围= 20-21)
     比较list[20]('U')和'U':找到它!完了。

比较两者:

  • 二进制搜索需要对输入数据进行排序;线性搜索不
  • 二进制搜索需要订购比较;线性搜索只需要相等比较
  • 二进制搜索具有复杂度O(log n);线性搜索具有前面讨论的复杂度O(n)
  • 二进制搜索需要随机访问数据;线性搜索只需要顺序访问(这可能非常重要 - 这意味着线性搜索可以任意大小的数据)

答案 1 :(得分:58)

将其视为在电话簿中找到自己的方式的两种不同方式。线性搜索从头开始,读取每个名称,直到找到您要查找的内容。另一方面,二进制搜索是当你打开书本(通常在中间)时,查看页面顶部的名称,并确定你要找的名字是大于还是小于你的名字。正在寻找。如果您要查找的名称更大,那么您将继续以这种方式搜索本书的上半部分。

答案 2 :(得分:14)

线性搜索的工作原理是查看数据列表中的每个元素,直到找到目标或到达目标。这导致给定列表上的O(n)性能。 二进制搜索带有必须对数据进行排序的先决条件。我们可以利用这些信息来减少查找目标所需的项目数量。我们知道,如果我们查看数据中的随机项(比如中间项)并且该项大于我们的目标,那么该项右侧的所有项也将大于我们的目标。这意味着我们只需要查看数据的左侧部分。基本上,每次我们搜索目标和未命中时,我们都可以消除剩余项目的一半。这给了我们一个很好的O(log n)时间复杂度。

请记住,即使使用最有效的算法,排序数据也总是比线性搜索慢(最快的排序算法是O(n * log n))。因此,您不应该仅仅为了稍后执行单个二进制搜索而对数据进行排序。但是如果你要执行许多搜索(比如说至少是O(log n)搜索),那么对数据进行排序可能是值得的,这样你就可以执行二进制搜索。在这种情况下,您可能还会考虑其他数据结构,例如哈希表。

答案 3 :(得分:5)

线性搜索从值列表的开头开始,并逐个检查以查找您要查找的结果。

二进制搜索从排序数组的中间开始,并确定您要查找的值的哪一侧(如果有)。然后以相同的方式再次搜索数组的“一半”,每次将结果分成两半。

答案 4 :(得分:5)

请务必考虑更快的二元搜索的胜利是否值得保持列表排序(能够使用二进制搜索)的成本。即如果你有很多插入/删除操作,只有偶尔的搜索,二进制搜索总的来说可能比线性搜索慢。

答案 5 :(得分:3)

尝试此操作:选择一个随机名称“姓氏,名字”,然后在电话簿中查找。

第一次:从书的开头开始,读取名字直到找到它,或者找到按字母顺序排列的地方,并注意它不在那里。

第二次:在中间点打开书并查看页面。问问自己,这个人应该向左还是向右。无论哪一个,取1/2并找到它的中间。重复此过程,直到找到条目所在的页面,然后将相同的过程应用于列,或者像以前一样沿着页面上的名称线性搜索。

计算两种方法并报告回来!

[如果您拥有的只是一个名单列表,而不是排序......,还要考虑哪种方法会更好。]

答案 6 :(得分:2)

线性搜索也称为顺序搜索,从头开始依次查看每个元素,以查看数据结构中是否存在所需元素。当数据量很小时,这种搜索很快。它很容易,但是所需的工作量与要搜索的数据量成正比。如果不存在所需的元素,加倍元素的数量将使搜索时间加倍。 / p>

二进制搜索对于更大的数组是有效的。在这里我们检查中间元素。如果值大于我们正在寻找的值,那么查看上半部分;否则,查看下半部分。重复此操作,直到找到所需的项目。必须对表进行排序以进行二进制搜索。它在每次迭代时消除了一半的数据。它是对数的。

如果我们有1000个要搜索的元素,二进制搜索大约需要10步,线性搜索需要1000步。

答案 7 :(得分:2)

二进制搜索在O(logn)时间运行,而线性搜索在O(n)次运行,因此二进制搜索具有更好的性能

答案 8 :(得分:2)

线性搜索向下查看列表,一次查看一个项目,而不跳转。在复杂性方面,这是一个O(n)搜索 - 搜索列表所用的时间会以与列表相同的速率变大。

二进制搜索是指从排序列表的中间开始,并查看是否大于或小于您要查找的值,这将确定该值是否在列表的第一个或后半部分中。跳到子列表的中间位置,然后再次进行比较等。这几乎就是人类通常在字典中查找单词的方式(尽管我们使用更好的启发式方法,显然 - 如果你正在寻找“猫”,你不会从“M”开始)。在复杂性方面,这是一个O(log n)搜索 - 搜索操作的数量比列表的增长速度慢,因为每次操作都会使“搜索空间”减半。

答案 9 :(得分:0)

Linear Search查看项目,直到找到搜索到的值。

效率:O(n)

示例Python代码:

test_list = [1, 3, 9, 11, 15, 19, 29]
test_val1 = 25
test_val2 = 15

def linear_search(input_array, search_value):
    index = 0
    while (index < len(input_array)) and (input_array[index] < search_value):
        index += 1
    if index >= len(input_array) or input_array[index] != search_value:
        return -1

    return index


print linear_search(test_list, test_val1)
print linear_search(test_list, test_val2)

Binary Search找到数组的中间元素。检查中间值是大于还是小于搜索值。如果它更小,它将获得数组的左侧并找到该部分的中间元素。如果它更大,则获取数组的正确部分。它循环操作,直到找到搜索到的值。或者如果数组中没有值,则完成搜索。

效率:O(logn)

示例Python代码:

test_list = [1, 3, 9, 11, 15, 19, 29]
test_val1 = 25
test_val2 = 15

def binary_search(input_array, value):
    low = 0
    high = len(input_array) - 1
    while low <= high:
        mid = (low + high) / 2
        if input_array[mid] == value:
            return mid
        elif input_array[mid] < value:
            low = mid + 1
        else:
            high = mid - 1

    return -1


print binary_search(test_list, test_val1)
print binary_search(test_list, test_val2)

此外,您还可以在此处查看有关线性和二进制搜索的可视化信息:https://www.cs.usfca.edu/~galles/visualization/Search.html

答案 10 :(得分:0)

为了清楚理解,请查看我的codepen实现https://codepen.io/serdarsenay/pen/XELWqN

最大的区别是需要在应用二进制搜索之前对样本进行排序,因此对于大多数&#34;正常大小的&#34; (意思是有争议的)样本将更快地用线性搜索算法进行搜索。

这是javascript代码,对于html和css以及完整运行的示例请参考上面的codepen链接。

var unsortedhaystack = [];
var haystack = [];
function init() {
  unsortedhaystack = document.getElementById("haystack").value.split(' ');
}
function sortHaystack() {
  var t = timer('sort benchmark');
  haystack = unsortedhaystack.sort();
  t.stop();
}

var timer = function(name) {
    var start = new Date();
    return {
        stop: function() {
            var end  = new Date();
            var time = end.getTime() - start.getTime();
            console.log('Timer:', name, 'finished in', time, 'ms');
        }
    }
};

function lineerSearch() {
  init();
  var t = timer('lineerSearch benchmark');
  var input = this.event.target.value;
  for(var i = 0;i<unsortedhaystack.length - 1;i++) {
    if (unsortedhaystack[i] === input) {
      document.getElementById('result').innerHTML = 'result is... "' + unsortedhaystack[i] + '", on index: ' + i + ' of the unsorted array. Found' + ' within ' + i + ' iterations';
      console.log(document.getElementById('result').innerHTML);
      t.stop(); 
      return unsortedhaystack[i]; 
    }
  }
}

function binarySearch () {
  init();
  sortHaystack();
  var t = timer('binarySearch benchmark');
  var firstIndex = 0;
  var lastIndex = haystack.length-1;
  var input = this.event.target.value;

  //currently point in the half of the array
  var currentIndex = (haystack.length-1)/2 | 0;
  var iterations = 0;

  while (firstIndex <= lastIndex) {
    currentIndex = (firstIndex + lastIndex)/2 | 0;
    iterations++;
    if (haystack[currentIndex]  < input) {
      firstIndex = currentIndex + 1;
      //console.log(currentIndex + " added, fI:"+firstIndex+", lI: "+lastIndex);
    } else if (haystack[currentIndex] > input) {
      lastIndex = currentIndex - 1;
      //console.log(currentIndex + " substracted, fI:"+firstIndex+", lI: "+lastIndex);
    } else {
      document.getElementById('result').innerHTML = 'result is... "' + haystack[currentIndex] + '", on index: ' + currentIndex + ' of the sorted array. Found' + ' within ' + iterations + ' iterations';
      console.log(document.getElementById('result').innerHTML);
      t.stop(); 
      return true;
    }
  }
}