• python的算法:二分法查找(2)--bisect模块


    Python 有一个 bisect 模块,用于维护有序列表。bisect 模块实现了一个算法用于插入元素到有序列表。在一些情况下,这比反复排序列表或构造一个大的列表再排序的效率更高。Bisect 是二分法的意思,这里使用二分法来排序,它会将一个元素插入到一个有序列表的合适位置,这使得不需要每次调用 sort 的方式维护有序列表。

    先看一个最简单的用法:

    import bisect
    
    l=[1,3,3,6,8,12,15]
    x=4
    
    left_insert_point=bisect.bisect_left(l,x)
    right_insert_point=bisect.bisect_right(l,x)
    print(left_insert_point)
    print(right_insert_point)

    两个的结果,都是3

    import bisect
    
    l=[1,3,3,6,8,12,15]
    x=3
    
    left_insert_point=bisect.bisect_left(l,x)
    right_insert_point=bisect.bisect_right(l,x)
    print(left_insert_point)
    print(right_insert_point)

    结果分别是1,3

    bisect的模块不复杂,现在,我们先看bisect_left这个函数:

    def bisect_left(a, x, lo=0, hi=None):
        """Return the index where to insert item x in list a, assuming a is sorted.
        The return value i is such that all e in a[:i] have e < x, and all e in
        a[i:] have e >= x.  So if x already appears in the list, a.insert(x) will
        insert just before the leftmost x already there.
        Optional args lo (default 0) and hi (default len(a)) bound the
        slice of a to be searched.
        """
    
        if lo < 0:
            raise ValueError('lo must be non-negative')
        if hi is None:
            hi = len(a)
        while lo < hi:
            mid = (lo+hi)//2
            if a[mid] < x: lo = mid+1
            else: hi = mid
        return lo

    这里,假定的,就是,a是一个有序的数组。

    假设,我们有这么一个数组:

    p=[1,4,3,3,6,8,12,15,0,9,3,28]

    这实际上,p不是有序的e。

    根据bisect_left的算法,每次都是二分。如果查找4的插入位置,当找到3的时候,就停止找了。所以,返回是4.

    再看bisect_right:
    def bisect_right(a, x, lo=0, hi=None):
        """Return the index where to insert item x in list a, assuming a is sorted.
        The return value i is such that all e in a[:i] have e <= x, and all e in
        a[i:] have e > x.  So if x already appears in the list, a.insert(x) will
        insert just after the rightmost x already there.
        Optional args lo (default 0) and hi (default len(a)) bound the
        slice of a to be searched.
        """
    
        if lo < 0:
            raise ValueError('lo must be non-negative')
        if hi is None:
            hi = len(a)
        while lo < hi:
            mid = (lo+hi)//2
            if x < a[mid]: hi = mid
            else: lo = mid+1
        return lo

    类似的,不多做描述。

  • 相关阅读:
    c# where(泛型类型约束)
    jQuery自定义插件
    jQuery插件定义
    SQL中merge into用法
    .net framework 4.5安装失败
    jQuery操作Form表单元素
    在WebAPI使用Session
    大数据量数据库设计与优化方案(SQL优化)
    修改NUGET包默认存放位置
    C#知识体系(一) 常用的LInq 与lambda表达式
  • 原文地址:https://www.cnblogs.com/aomi/p/7114930.html
Copyright © 2020-2023  润新知