二分查找

二分查找

    二分查找也称折半查找(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;
 }
posted @ 2022-06-16 21:57  青眼高歌  阅读(80)  评论(0)    收藏  举报