二分查找(递归和非递归)
顺序查找的时间复杂度最糟为O(n),而二分查找的时间复杂度为O(log n)
1、非递归
def binary_search(arr, item): low = 0 high = len(arr)-1 while low<=high: # 当左指针大于右指针的时候,则说明没找到,结束循环 mid = (low+high)//2 value = arr[mid] if value > item: high = mid - 1 # 如果比中间那个数小,则右指针向左移 elif value < item: low = mid + 1 # 如果比中间那个数大,则左指针向右移 else: return mid return None a = [1,2,3,4,5,6,7,8,9,10] ret = binary_search(a, 3)
2.递归(不断通过移动左右指针缩小查找范围)
def BinarySearch(arr,left,right,item): mid = (right+left)//2 if arr[mid]==item: return mid if left>right: # 先进行条件判断,保证不会无限递归 return None elif item > arr[mid]: return BinarySearch(arr,mid+1,right,item) elif item < arr[mid]: return BinarySearch(arr,left,mid-1,item)
ret = BinarySearch([1,2,4,5,7],0,4,0) print(ret)
二分查找的两种写法:循环条件都是left<right,循环结束时,left==right
区间分为:[left, mid, mid+1, right] right=mid, left=mid+1;
区间分为:[left, mid-1, mid, right] right=mid-1, left=mid;此时求mid应该向上取整 (left+right+1)/2,否则会死循环
如果循环条件写为left<=right,则循环结束时,left - right = 1
关于旋转数组的几道题:(二分查找不一定是要整个数组有序,而是左右两段有一段有序就可二分查找)
1、搜索旋转排序数组
二分查找不一定是对原数组进行二分查找,有可能是对索引进行查找: