要求线性表中的记录必须是关键码有序,线性表必须采用顺序存储。
思路:
在有序表中,取中间记录作为比较对象,也就是每次让mid指向序列的中间元素。
若查找的元素与mid指向的值相等,则查找成功,
若查找的值小于mid指向的元素,则在mid指向元素的左半区继续查找;
若给定的值大于中间记录的关键字,那就在mid指向元素的右半区查找,
不断重复,所以会有两种情况, 一种是查找成功, 一种是查找失败。
1. 查找成功: a[mid] = key; 此时返回索引即可 return mid;
2. 查找失败: 假设查找元素33, 当low==high的时候,还没有查到, 但仍然符合外层循环条件low<=high,因为a[mid]>key, 所以, 执行high = mid-1; 执行完这一句,low<=high就不满足了,因为之前low==high, 此时high-1, 所以不满足外层循环条件,退出循环。
如果在循环过程中找到了,就会返回索引, 如果退出了循环,说明在整个循环过程中都没有找到,直接返回0表示没找到。
int Binart_Search(int a[], int n, int key){
int low, high,mid;
//此数组从索引为1的位置开始查找
low = 1;
high = n;
while(low<=high){
mid = (low+high)/2;
if(key<a[mid]){
high = mid-1;
}else if(key>a[mid]){
low = mid+1;
}else{
return mid;
}
}
return 0;
}
注意: 将一个线性表从两边往中间找,当low=high时, 说明表找完了,此时k和a[mid]如果相等,则放回min, 如果不相等,再进行一趟循环,进入循环后,此时low>high,此时退出循环了,如果退出循环都没有返回一个索引,说明没找到,则退出循环后,返回0表示没找到.
折半查找的递归方式:
int Binart_Search(int a[], int low, int high, int key){
//如果查到了,就返回mid,如果没查到,则一直递归,当low=high时候,还没查到,
//再递归一趟,则low>high, 返回0;
if(low>high){
return 0;
}
else{
int mid = (low+high)/2;
if(key<a[mid]){
return Binart_Search(a,low,mid-1,key)
}else if(key>a[mid]){
return Binart_Search(a,mid+1,high,key)
}else{
return mid;
}
}
查找效率分析:
ASL成功 = (1*1+2*2+3*4+4*4) / 11 = 3
1.当查找元素29元素时候, 只需要对比1次,
2. 当查找第二层13元素时候,需要对比2次, 当查找第二层37元素的时候,需要对比2次,所以总共可能的需要是2*2次
3. 当查找第三层7元素的时候, 需要3对比次,查找16元素的时候,需要对比3次,第三层有4个结点,总共需要对比4*3次数。
所以成功将所有结点对比的次数相加, 去和结点元素个数11相, 就是每个元素查找成功的平均效率。
ASL失败=(3*4 + 8*4) / 12 = 11/3
看查找失败的平均效率,那就看失败的结点即可 , 第三层有4个结点,查找每个结点需要对比3次,所以第三层需要对比4*3次数, 第四层哟与8个结点, 每个结点需要对比4次, 所以第四层总共需要对比8*4次, 查找失败的结点有12个, 所以每个结点失败大的可能性是总次数除以12, 即为查找失败的平均效率。