剪枝搜索
剪枝搜索是搜索中常用的一个方法,Binary Search就是一个经典的剪枝搜索例子,在Biniary Search中
int binarySearch(int A[], int low, int high, int key) { int mid; while (low <= high) { mid = (low + high) >> 1; if (key < A[mid]) high = mid - 1; else if (key > A[mid]) low = mid + 1; else return mid; } return -1; }
我们可以明显看到,当目标被锁定在一半区域内时,就剪掉另一半,并对所在的一半进行搜索。而此时问题化简成为一个只有一半数据规模的子问题,递归这一过程,最终就可以在常数时间解决搜索问题。
另一个剪枝搜索的经典实例是寻找一组数中第K小的数的值,直观的想法是进行一次排序,而后求解。但即使是使用最合适于此问题的堆排序,也要用到O(NlogN)的时间,实际上,利用剪枝搜索有一种O(n)时间的算法如下:
选取数组中一个数P,遍历数组,将所有数据与P比较,小于P的数字置于集合S1,等于P的数字置于集合S2,大于P的数字置于集合S3
若S1.size>K,舍弃S2,S3,以S1为基础重复此问题。
否则 若S1.size+S2.size>K,则P为第K个数的值。
否则 舍弃S1,S2,以S3为基础重复此问题。
代码以后补
对于剪枝搜索问题的复杂度,我们可以看到
T(n)=T((1-f)*n)+O(n^k),最终的复杂度取决于k即为O(n^k),当n趋于无穷时,解决问题的实质复杂度和解决子问题的复杂度趋于一致。
(例如,对于Binary Search,T(n)=T(n/2)+C
设n=2^k,则有T(2^k)=T(2^(k-1))+C=(T(2^(k-2))+C)+C=T(1)+k*C
即T(n)=log(n)*C+T(1),所以binary search是一个O(log(n))的算法,在n趋于无穷时log(n)趋于常数代价)