二分查找
给出一个有序数组A[0...n-1]和一个值key,返回key在A[]中的位置或者不存在,要求log n复杂度。
C标准库中有一个bsearch(),原型为:
void * bsearch ( const void * key, const void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );
bsearch()返回第一个找到的位置,而不是首个位置。
通用的方法:给出元素首次出现的位置(最小下标)
int bs(int A[], int low, int high, int key) { int mid; while (low < high) { mid = (high-low)/2 + low; if (A[mid] < key) low = mid+1; else high = mid; } return (A[low]==key) ? low:-1; }
分析:
1. 循环终止的条件是low>=high, 如果传入的low<high,那么必然不会出现low>high的情况也即循环只在low=high时终止,因为在while循环中mid=(high+low)/2 < high,low<=mid+1<=high;
2. 如果A[low, high]中有值为key的元素,返回的是最小下标:
(1)可以确定的是A[high]>=key总是成立的,因为初始时A[high]>=key,且只有A[mid]>=key时才更新high;
(2)更新low的条件是A[mid]<key => A[low]<key,即low只在A[low]<key时更新,更新后A[low=mid+1]<=key && A[mid]<key,所以A[low]=key时,low为最小下标,low最终更新为A[low]=key;
(3)当low=high即循环终止时,A[high]>=key,A[low]=key,所以A[high]=A[low]=key,且low为最小下标
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步