搜索是对数据信息的搜索。数据信息通常以集合的形式存在。所谓集合,就是指数据类型一致的元素的组成的一个汇集。当信息量较少,整个集合元素都存放在内存中,称为表。否则,称为文件。搜索运算是表和文件上的最典型运算。
二分搜索的基本思想是:设有序表(a0,a1,a2,…,an-1),以元素am为划分点,将表分成(a0,a1,a2,…,am-1)和(am+1,…,an-1)两个表。将am的关键字值与x作比较。
比较结果有三种可能性:
(1) x < am:若x在表中,则必在子表(a0,a1,…,am-1)中,此时在该子表内进行二分搜索;
(2) x == am:搜索成功;
(3) x > am:若x在表中,则必在子表(am+1,am+2,…,an-1)中,此时在该子表内进行二分搜索。
由分割点的不同,可以得到不同的二分搜索方法。如:对半搜索、一致对半搜索、斐波那契搜索和插值搜索等。
对半搜索是二分搜索中的一种,分割点为表的中点元素。
若当前搜索的子表为(alow,alow+1,…,ahigh)则 i=(low+high)/2其中,i、low和 high均为元素在表中的序号,low表示表的左端,high表示表的右端。
程序6.5 对半搜索的递归算法
template <class T>
ResultCode ListSet<T>::Search( T& x)const {
int i = BSearch(x,0,n-1);
if (i == -1) return NotPresent;
x = l[i];
return Success;
}
template <class T>
int ListSet<T>::BSearch(T& x, int low, int high)const{
if (low <= high) {
int m = (low+high)/2; //对半分割
if (x < l[m]) return BSearch(x, low, m-1);
else if (x>l[m]) return BSearch(x, m+1, high);
else return m; //搜索成功
}
return -1; //搜索失败
} <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
程序6.6 对半搜索的迭代算法
template <class T>
ResultCode ListSet<T>::Search(T& x)const
{
int m,low=0,high=n-1;
while (low<=high) {
m=(low+high)/2;
if (x<l[m]) high=m-1;
else if (x>l[m]) low=m+1;
else {
x=l[m];return Success; //搜索成功
}
}
return NotPresent; //搜索失败
}
对半搜索算法在成功搜索的情况下,关键字值之间的比较次数不超过log2n+1。平均时间复杂度为O(log2n)。