练习
有一个无序序列[37,99,73,48,46,488,48,32,4],对其先排序输出新列表
分别尝试插入20,40,41到这个新序列中合适的位置保证其有序.
- 思路
排序后二分法查找适当位置插入数值
排序使用sorted解决,假设升序输出
查找插入点,使用二分查找完成
lst = [37,99,73,48,46,488,48,32,4,8]
def insert_sort(orderlist,i):
orderlist.sort()
print(orderlist)
ret = orderlist[:]
low = 0
high = len(ret) ##
while low<high:
mid = (low+high)//2 ##insert是从索引位置插入,而非之后插入.
if ret[mid] < i: ##控制倒叙示的插入
low = mid + 1
else:
high = mid-1
else:
ret.insert(low,i)
return ret
print(insert_sort(lst,500))
out :[4, 8, 32, 37, 46, 48, 48, 73, 99, 488, 500]
- high = len(oderlist),去掉减1,不影响除2
但影响循环时的判断,导致少循环一次(等于时无法进入)
多执行一次后,insert索引会超界,但是insert支持超界,会在尾部追加 - 上面是二分法的核心思想
二分
- 二分的前提是有序的,否则不可二分
- 二分查找算法的时间复杂度为O(log n)
- python提供了二分法的模块
bisect模块
bisect模块提供的函数有:
- bisect.bisect_left(a,x,lo=0,hi=len(a))
- bisect.bisect_right(a,x,lo=0,hi=len(a)) 或者 bisect.bisect(a,x,lo=0,hi=len(a))
查找在有序列表a中插入x的index.lo和hi用于指定列表的区间,默认是使用整个列表
如果x已经存在,在其左边插入,返回值为index - left和right控制的是出现两个相等的值是插入左边还是右边.例如列表中有两个4,默认右侧插入
- bisect.bisect_left(a,x,lo=0,hi=len(a))
在序列啊中插入x - bisect.insort_right(a,x,lo=0,hi=len(a) bisect.bisect(a,x,lo=0,hi=len(a))
如果x存在,在右侧插入 - 总结:
bisect用于查找
insort用于插入默
默认重复时从右边插入