二分查找算法的Python实现

问题

二分查找

list.index()无法应对大规模数据的查询,需要用其它方法解决,这里谈的就是二分查找

思路说明

在查找方面,python中有list.index()的方法。例如:

>>> a=[2,4,1,9,3]           #list可以是无序,也可以是有序
>>> a.index(4)              #找到后返回该值在list中的位置
1
>>> a.index(5)              #如果没有该值,则报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 5 is not in list

这是python中基本的查找方法,虽然简单,但是,如果由于其时间复杂度为O(n),对于大规模的查询恐怕是不足以胜任的。二分查找就是一种替代方法。

二分查找的对象是:有序数组。这点特别需要注意。要把数组排好序先。怎么排序,可以参看我这里多篇排序问题的文章。

基本步骤:

  1. 从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;
  2. 如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。
  3. 如果在某一步骤数组为空,则代表找不到。

这种搜索算法每一次比较都使搜索范围缩小一半。时间复杂度:O(logn)

解决(Python)

def binarySearch(lst, value,low,high):          #low,high是lst的查找范围
    if high < low:
        return -1
    mid = (low + high)/2
    if lst[mid] > value:
        return binarySearch(lst, value, low, mid-1)
    elif lst[mid] < value:
        return binarySearch(lst, value, mid+1, high)
    else:
        return mid

#也可以不用递归方法,而采用循环,如下:

def bsearch(l, value):
    lo, hi = 0, len(l)-1
    while lo <= hi:
        mid = (lo + hi) / 2
        if l[mid] < value:
            lo = mid + 1
        elif value < l[mid]:
            hi = mid - 1
        else:
            return mid
    return -1

if __name__ == '__main__':
    l = range(50)
    print binarySearch(l,10,0,49)
    print bsearch(l,10)

对于python,不能忽视其强大的标准库。经查阅,发现标准库中就有一个模块,名为:bisect。其文档中有这样一句话:

This module provides support for maintaining a list in sorted order without having to sort the list after each insertion. For long lists of items with expensive comparison operations, this can be an improvement
over the more common approach. The module is called bisect because it uses a basic bisection algorithm to do its work. The source code may be most useful as a working example of the algorithm (the boundary conditions are already right!).

当我把这段话输入到百度翻译中,天才的百度翻译给我的结果是:

这个模块提供支持,维护list in order for without having to类法术the list After each插入。久lists of items以及昂贵的比较操作,这可以改善over the more common approach年。bisect because it is called the模块基本分割算法用to do its work。源代码可能是最有用的工作example of the算法(the边界条件are already right!)。

这就是百度的水平,只可惜在贵国不能用google。

看官就凭借自己的英语水平理解吧。这段话的关键点是在说明:

  • 模块接受排序后的列表。
  • 本模块同样适用于长列表项。因为它就是用二分查找方法实现的,有兴趣可以看其源码(源码是一个很好的二分查找算法的例子,特别是很好地解决了边界条件极端的问题.)
  • 关于bisect模块的更多内容,可以参看官方文档

下面演示这个模块的一个函数

from bisect import *

def bisectSearch(lst, x):
    i = bisect_left(lst, x)         #bisect_left(lst,x),得到x在已经排序的lst中的位置
    if i != len(lst) and lst[i] == x:
        return i
    raise ValueError

if __name__=="__main__":
    lst = sorted([2,5,3,8])
    print bisectSearch(lst,5)

python模块,赞了。

二分查找算法的Python实现

时间: 2024-08-20 01:13:06

二分查找算法的Python实现的相关文章

python函数:递归函数及二分查找算法

本文和大家分享的主要是python的递归函数及二分查找算法相关内容,一起来看看吧,希望对大家学习python有所帮助. 一.递归的定义 def story(): s = """ 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? """ print(s) story() story() 老和尚讲故事 递归的定义 -- 在一个函数里再调用这个函数本身.这种魔性的使用函数的方式就叫做 递归 . 递归的最大深度:997 1.python递归最大层

Python 实现二分查找算法

最近在学习python,由于在面试中,二分查找算法面试率极高,所以使用python做了一个实现. def search1(sequence, number): lower = 0 upper = len(sequence) - 1 while lower <= upper: mid = (lower + upper) // 2 if number > sequence[mid]: lower = mid + 1 elif number < sequence[mid]: upper = m

Python——递归、二分查找算法

递归函数 1. 递归 (1)什么是递归:在函数中调用自身函数(2)最大递归深度:默认997/998--是Python从内存角度出发做的限制 n = 0 def story(): global n n+= 1 print(n) story() #997/998 story() (3)修改最大深度:最好不要改--递归次数太多,则不适合用递归解决问题 import sys sys.setrecursionlimit(2000) #1997/1998 2. 递归的优点 会让代码变简单 3. 递归的缺点

python之路——二分查找算法

楔子 如果有这样一个列表,让你从这个列表中找到66的位置,你要怎么做? l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] 你说,so easy! l.index(66)... 我们之所以用index方法可以找到,是因为python帮我们实现了查找方法.如果,index方法不给你用了...你还能找到这个66么? l = [2,3,5,10,15,16,18,22,26,30,32,35,41,

python--递归、二分查找算法

递归 初识递归 递归的定义--在一个函数里再调用这个函数本身 现在我们已经大概知道刚刚讲的story函数做了什么,就是在一个函数里再调用这个函数本身,这种魔性的使用函数的方式就叫做递归. 刚刚我们就已经写了一个最简单的递归函数. 递归的最大深度--997 正如你们刚刚看到的,递归函数如果不受到外力的阻止会一直执行下去.但是我们之前已经说过关于函数调用的问题,每一次函数调用都会产生一个属于它自己的名称空间,如果一直调用下去,就会造成名称空间占用太多内存的问题,于是python为了杜绝此类现象,强制

自学Python3.6-算法 二分查找算法

自学Python之路-Python基础+模块+面向对象自学Python之路-Python网络编程自学Python之路-Python并发编程+数据库+前端自学Python之路-django 自学Python3.6-算法 二分查找算法 .... 原文地址:https://www.cnblogs.com/yaoyaojcy/p/10596912.html

二分查找算法的 JavaScript 实现

二分查找在查找[指定值]在[有序]数据中的[位置]时是一种高效的算法. 以下仅提供 ES5 版本. var arr = [0, 2, 4, 27, 28, 54, 67, 74, 75, 79, 86, 97, 289, 290, 678] function binarySearch(arr, val) { var start = 0, end = arr.length - 1; while (start <= end) { var mid = Math.floor((start + end)

算法_001_二分查找算法

 二分查找算法是在有序数组中用到的较为频繁的一种算法,在未接触二分查找算法时,最通用的一种做法是,对数组进行遍历,跟每个元素进行比较,其时间为O(n).但二分查找算法则更优,因为其查找时间为O(lgn),譬如数组{1, 2, 3, 4, 5, 6, 7, 8, 9},查找元素6,用二分查找的算法执行的话,其顺序为:     1.第一步查找中间元素,即5,由于5<6,则6必然在5之后的数组元素中,那么就在{6, 7, 8, 9}中查找,    2.寻找{6, 7, 8, 9}的中位数,为7,7>

Java学习之二分查找算法

好久没写算法了.只记得递归方法..结果测试下爆栈了. 思路就是取范围的中间点,判断是不是要找的值,是就输出,不是就与范围的两个临界值比较大小,不断更新临界值直到找到为止,给定的集合一定是有序的. 自己写的代码: 1 package com.gh; 2 3 import java.util.Arrays; 4 /** 5 * 二分查找算法实现 6 * @author ganhang 7 * 8 */ 9 public class Search { 10 public static void mai