二分搜索算法
简介
二分搜索算法又叫折半查找算法,是一种快速的搜索算法。其主要思想是依靠与中间的元素进行比较来逐步排除一半的元素。但这要求待查找列表是有序序列。
伪代码
procedure binary search(x: 整数, A1, A2,..., An: 递增整数)
left := 1 {left是搜索区间的左端点}
right := n {right是搜索区间的右端点}
while left < right
m := [(left + right) / 2] (向下取整)
if x > A[m] then left := m + 1
else right := m
if x = A[left] then location := left
else location := 0
return location {location 是等于x的项的下标,如果是0,则没有找到}
C代码
int binarySearch(const int a[], const int aim, const int len) { int low = 0; // left int high = len - 1; // right int mid; // middle while(low <= high) { mid = (high + low) / 2; if(a[mid] == aim) return mid; else if(a[mid] > aim) high = mid - 1; else low = mid + 1; } return -1; // if a[] don't contain it. }
缺点
- 在进行搜索前,必须进行排序,以保证列表有序。
算法复杂度
- 最优情况下的复杂度
当列表的中间项就是待查找元素时,只需进行2次比较。因而算法复杂度为 Θ(1)
- 最坏情况下的复杂度
当列表中无待查找项时,就需要 3*logN + 1 次比较(N是列表中的元素数目),因而算法复杂度为 Θ(logN)
- 平均复杂度
当第一次就被查找到时,需要2次比较。第二次查找到时需要额外3次比较,第三次又需要额外的3次比较,因而平均比较次数为 (2+5+8+...+3*N-1)/N = (3*N+1)/2 次比较。因而算法复杂度为 Θ(N)
注解
在伪代码中,无论第一个是不是待查找数据都不会结束程序,而会遍历完之后与待查找数据进行比较。因此会使得算法复杂度不会因为情况好坏而改变,复杂度固定为Θ(logN)。在C代码中给予了改进,使得在最优情况下复杂度保持在常数级别。