二分查找
二分查找
二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
/*二分查找有序数组
arry[] int数组
num 要查找的int对象
size 数组的长度
*/
int binary_search(int arry[] , int num ,int size) {
int left = 0;//左下标
int right = size - 1;//右下标
while (left <= right) {//当左下标小于等于右下标时持续二分查找
int mid = (left+right) //中间元素的下标
if (arry[mid] < num)//如果中间下标小于目标值,左下标+1,继续二分查找
left = mid + 1;
else if (arry[mid] > num)//如果中间下标大于目标值,右下标-1,继续二分查找
right = mid - 1;
else //如果中间下标正好等于目标值,则返回
return mid;
}
return -1;
}
int main() {
int arry[] = { 1,2,3,4,5,6,7,8,9,10 };
int num = 7;
int size = sizeof(arry) / sizeof(arry[0]);//数组长度
int result = binary_search(arry, num,size);
printf("%d : %d",num,result);
return 0;
}
为什么该处不在函数体内进行数组长度计算呢?
函数体的形参是数组,而数组就是指针,那么传到函数体内的就是数组首个元素的地址,(地址在win32下是4位,在win64下是8位),那么int size=sizeof(arry)/sizefo(arry[0]) 就是数组的首元素的地址/数组首元素,int数组元素是4位,所有size=1。这明显是不正确的,所以就要在main函数中来求size,将size传入函数体内。
int main(){
int arr[10] ={1,2,3,4,5,6,7,8,9,10,};
int n = 0;
int binsearch(int size,int arr[],int n);
int size = sizeof(arr)/sizeof(arr[0]);
printf("please input the found number:\n");
scanf("%d",&n);
printf("the result is %d\n",binsearch(size,arr,n));
return 0;
}
/**
* 二分查找有序数组中的元素
* @param size 数组的长度
* @param arr 有序数组
* @param n 所要查找的元素
* @return 返回所要查找元素的下标
*/
int binsearch(int size,int arr[],int n){
int left = 0;//左下标
int right = size-1;//右下标
int middle = (left+right)/2;//中间元素的下标,也是返回值
//循环更新左、右、中间元素下标
//循环条件为中间元素不等于所要查找的元素
for(;arr[middle] != n;){
//查找元素在中间值的左边
if(arr[middle]>n){
right = middle;//更新右下标为中间元素下标
middle = (left+right)/2;//更新中间元素下标
}
//查找元素在中间值的右边
else if(arr[middle]<n){
left = middle;//更新左下标为中间元素下标
middle = (left+right)/2;//更新中间元素下标
}
}
//若所查找元素就是中间元素,直接返回
return middle;
}