Python的二分查找与插入bisect模块,查询函数主要使用bisect.bisect() ,bisect.bisect_left() ,bisect.bisect_right() ,插入函数主要使用bisect.insort() 函数 参数输入格式都为(array, item)
其中bisect.bisect() ,bisect.bisect_left() ,bisect.bisect_right() 用于查询目标值的最佳插入位置,三者的差异在于:
- 当查询的值在数组中且数组不重复时:bisect返回查询值所在下标+1,bisect_left返回查询值所在下标,bisect_right返回查询值所在下标+1(或者说是第一个比目标值大的元素坐标):
nums_1 = [1,2,3,4,5]
res_bisect = bisect.bisect(nums_1, 1)
res_left = bisect.bisect_left(nums_1, 1)
res_right = bisect.bisect_right(nums_1, 1)
print(res_bisect, res_left, res_right)
结果:1 0 1
- 当查询的值在数组中且数组有重复元素时时:bisect返回查询值重复最后一位的下标+1,bisect_left返回查询值第一次出现的下标,bisect返回查询值重复最后一位的下标+1(或者说是第一个比目标值大的元素的下标)
nums_2 = [1,2,2,3,4,5]
res_bisect = bisect.bisect(nums_2, 2)
res_left = bisect.bisect_left(nums_2, 2)
res_right = bisect.bisect_right(nums_2, 2)
print(res_bisect, res_left, res_right)
结果:3 1 3
- 当查询的值不在数组中时:bisect, bisect_left和bisect_right返回结果一致,如果在数组中间就返回第一个比查询值大的元素的下标,如果比所有元素小返回0,比所有元素大则返回数组长度。即返回一个最佳插入的位置。
nums_3 = [1,2,2,3,3,4,5]
res_bisect = bisect.bisect(nums_3, 2.5)
res_left = bisect.bisect_left(nums_3, 2.5)
res_right = bisect.bisect_right(nums_3, 2.5)
print(res_bisect, res_left, res_right)
结果:3 3 3
nums_4 = [1,2,2,3,3,4,5]
res_bisect = bisect.bisect(nums_4, 0)
res_left = bisect.bisect_left(nums_4, 0)
res_right = bisect.bisect_right(nums_4, 0)
print(res_bisect, res_left, res_right)
结果:0 0 0
nums_5 = [1,2,2,3,3,4,5]
res_bisect = bisect.bisect(nums_5, 6)
res_left = bisect.bisect_left(nums_5, 6)
res_right = bisect.bisect_right(nums_5, 6)
print(res_bisect, res_left, res_right)
结果:7 7 7 最后,为了保持有序数组,插入函数使用bisect.insort() :
nums_6 = [1,2,3,4,4,5]
bisect.insort(nums_6, 4.3)
nums_6
结果:[1, 2, 3, 4, 4, 4.3, 5]
|