这里主要讲两种查找算法,一种是顺序查找算法,一种是折半(二分)查找算法,其中二分查找算法主要讲循环实现和递归实现两种方法。下面先看顺序查找。
顺序查找算法
顺序查找算法是按照数组中元素的顺序,按照从左往右或者从右往左的顺序遍历数组,将数组中的元素逐个与要查找的元素进行比较,如果找到,就返回相应的下标,如果到数组遍历完成都没有找到,就返回-1。
实现示例:
template<class T>
int query_array(T a[],T flag,const int len){ //len表示数组的长度
int result = -1;
for(int i=0;i<len;i++){
if(a[i]==flag){
result = i; //找到,将结果换为查找到的下标
break;
}
}
return result;
}
注: 在C++中,带有小数点的数字被默认是double类型的,所以在进行查找时,需要注意以下问题:
int main(){
float arr[] = {1.5,20,3.5,6.6,7.9,88.9,99.1};
int result = query_array(arr,float(6.6),7);
cout<<result<<endl; //结果为3
return 0;
}
在这段程序中,调用query_array时,传入的第二个参数为6.6,但这段程序是无法通过编译的,因为6.6会被默认为double类型,而方法中的第二个参数会被转化为float类型,所以就会出现错误,解决的方法之一就是将6.6强制转换为float类型,方法为float(6.6)
折半查找的循环实现
折半查找是一种高效的查找算法,但其对于查找的数组有要求,其要求所查找的数组必须是一个排好序的数组。其查找的原理是首先看数组中位于中间位置的那个值是否是要查找的值,如果是,则返回结果;如果比要查找的值小,就在右半边寻找,取右半个数组的中间值,继续依据此方法进行查找;如果比要查找的值大,就在左半边依照上面所说的方法继续查找。
下面以一个实例说明上述规则,首先,有一个数组:{1,2,3,4,4.1,4.2,5.1,6,9.2}
要查找数2的过程如下:
实现示例:
template<class T>
int query_array(T a[],T flag,const int len){
int result = -1;
int i=0;
int j=len-1;
int middle;
while(i<j){
middle=(i+j)/2;
if(a[middle]==flag){
result=middle;
break;
}
else if(a[middle]>flag){
j=middle-1;
}
else if(a[middle]<flag){
i=middle+1;
}
}
return result;
}
以上面的实例来测试:
int main(){
double arr[] = {1,2,3,4,4.1,4.2,5.1,6,9.2};
int result = query_array(arr,double(2),9); //由于2默认为int,所以必须将其强制转为double
cout<<result<<endl; //结果为1
return 0;
}
折半查找的递归实现
递归实现折半查找的要素在于根据中间值与目标值的大小关系调用查找算法,输入不同的左边界与右边界完成的,下满是其一个实现示例:
template<class T>
int query_array(T a[],const T flag, const int left,const int right){ //left表示要查找的数组的左边界下标,right表示要查找的数组的右边界下标
if(left<right){
int middle = (left+right)/2;
if(a[middle]==flag){
return middle; //找到所要找的元素,返回下标
}else if(a[middle]>flag){
return query_array(a,flag,left,middle-1); //所要找的元素在左半部分
}else if(a[middle]<flag){
return query_array(a,flag,middle+1,right); //所要找的元素在右半部分
}
}else{
return -1; //没找到
}
}
测试程序如下:
int main(){
double arr[] = {1,2,3,4,4.1,4.2,5.1,6,9.2};
int result = query_array(arr,double(2),0,8);
cout<<result<<endl; //结果为1
return 0;
}