查找抽象方法的实现_最简单的方法实现 Python数组二分查找算法

bisect 数组二分查找算法

不想自己手写二分查找?

可以,一个 import bisect 帮你完成开包即用的 Binary Search。

bisect 是一个python标准库,直接导入就可以使用。

方法1: bisect.bisect_left()
bisect.bisect_left(a, x, lo=0, hi=len(a))
参数说明:
  • a:表示插入的数组
  • x:即将插入到数组中的一个数值类型的元素
返回值:元素x插入到数组a后在数组中的位置索引(不执行插入操作,只计算索引,数组a保持不变),如果x在a中已经存在,则x插入到已存在元素的左侧。
例子:

2035b7bc163d835deefc9caf3d7e6ef3.png

可以看到,元素8在插入到数组a后的位置索引为 3,新插入的元素x(8)在已经存在数组a中的元素8的左侧。

方法2: bisect.bisect_right()
bisect.bisect_right(a, x, lo=0, hi=len(a))
参数说明:
  • a:表示插入的数组
  • x:即将插入到数组中的一个数值类型的元素
返回值:元素x插入到数组a后在数组中的位置索引(不执行插入操作,只计算索引,数组a保持不变),如果x在a中已经存在,则x插入到已存在元素的右侧。
例子:

dd3b5c7116bb9d809816b0037fc86fca.png

可以看到,元素8在插入到数组a后的位置索引为 4,新插入的元素x(8)在已经存在数组a中的元素8的右侧。

方法3: bisect.bisect()
bisect.bisect(a, x, lo=0, hi=len(a))

效果同 bisect_right,可以看作是 bisect_right 的缩写。

方法4: bisect.insort_left()
bisect.insort_left(a, x, lo=0, hi=len(a))

同 bisect_left 原理一致,只不过 bisect_left 不真正执行插入操作,而 insort_left 执行插入操作,数组a发生改变。

相当于

a.insert(bisect.bisect_left(a, x, lo, hi), x)
例子:

521fd6aef4a33b302d0597c5b604aa36.png

这里红圈的 8 就是插入的参数 x。

方法5: bisect.insort_right()
bisect.insort_right(a, x, lo=0, hi=len(a))

同 bisect_right 原理一致,只不过 bisect_right 不真正执行插入操作,而 insort_right 执行插入操作,数组a发生改变。

相当于

a.insert(bisect.bisect_right(a, x, lo, hi), x)
例子:

698e25eed8dc81b38a0b4bdfb76c5292.png

这里红圈的 8 就是插入的参数 x,注意和 insort_left 的区别。

方法6: bisect.insort()
bisect.insort(a, x, lo=0, hi=len(a))

效果同 insort_right,可以看作是 insort_right 的缩写。

应用

查询 x 是否在数组 a 中, 如果在返回位置索引
a=[1, 5, 7, 8, 9]

def index(a, x):
    i = bisect.bisect_left(a, x)
    if i != len(a) and a[i] == x:
        return i
    raise ValueError

b44982aebbc5e117d54b8751782bfa05.png

注意:如果有重复值,返回最左侧位置的索引

类似数据分组

函数 bisect() 还可以用于数字表查询。这个例子是使用 bisect() 从一个给定的考试成绩集合里,通过一个有序数字表,查出其对应的字母等级:90 分及以上是 'A',80 到 89 是 'B',以此类推。

def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
    i = bisect.bisect(breakpoints, score)
    return grades[i]

[grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]

445e41f09efbf7f327ab3fbd8f5c0b84.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值