1 #include "stdafx.h" 2 #include <iostream> 3 #include <exception> 4 #include<string> 5 using namespace std; 6 7 8 /*有序表查找-折半查找 9 折半查找有称为二分查找,线性表中的记录必须是关键码有序,通常是从小到大 10 线性表必须采用顺序存储. 11 基本思想:在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功; 12 若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字, 13 则在中间记录的右半区继续查找。不断重复上述过程.直到找到成功,或所有查找区域无记录,查找失败. 14 */ 15 16 int Binary_Search(int *a,int n,int key) 17 { 18 int low,high,mid; 19 low = 0; 20 high = n-1; 21 while(low<=high) 22 { 23 mid = (low+high)/2; 24 if(a[mid]>key) 25 { 26 high = mid-1; 27 } 28 else if(a[mid]<key) 29 { 30 low = mid+1; 31 } 32 else 33 return mid+1; 34 } 35 return -1; 36 } 37 38 int _tmain(int argc, _TCHAR* argv[]) 39 { 40 int nums[5]={1,2,3,4,5}; 41 42 cout<<Binary_Search(nums,5,2);//返回数字在数组中的位置,为2 43 44 return 0 ; 45 }
另外,为什么一定要是折半而不是折四分之一或者折更多呢?
mid = (low+high)/2 = low + (high-low)/2;
在这里如果将
mid 改为 mid = low + (high - low) *(key - a[low])/(a[high]-a[low]);//这就是插值
时间复杂度,也是O(logn),但是对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好很多.
但是,如果数组中分布类似{0,1,2,2000,2001,......,999998,999999)这种极端不均匀的数据,用插值查找未必就很合适了.