1.目的:
写一个程序,在一个_有序数组_中查找某元素,并打印其_下标_。
2.算法分析:
二分查找法(又称折半查找法),是一种通过_反复_确定数组中某部分中间元素,并与目标元素进行比较,从而逐步缩小查找范围,最终在数组中找到目标元素的一种算法。
具体方法:先将数组首元素与末元素下标相加除以二得到中间元素下标,然后用得到的下标找到对应的数,再把这个数与目标数进行比较。
情况1:这个数大于目标数,说明目标数在这个数与左值(首元素)之间。那么就将这个数减一并赋给右下标。
情况2:这个数小于于目标数,目标数则在这个数与右值(末元素)之间。那么就将这个数加一并赋给左下标。
情况3:两数刚好相等,那就直接找到了,返回下标即可。
出现情况1、2则循环往复,直至出现情况3为止。
分析完毕
3.实现过程:
主函数:
(1)我们先初始化一个有序数组,然后在里面选择一个要找的数并计算数组大小。
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k=7;
int sz=sizeof(arr)/sizeof(arr[0]);//计算arr大小
注意:不能在自定义函数内部使用sizeof(),原因如下:
a.数组在传参时传的是首字母的地址
void swap_1(int* arr1)//arr1是作为指针变量接收arr数组中首元素的地址
{
int sz=sizeof(*arr1)/sizeof(arr[0]);//值为1,故无法求出arr大小
}
swap_1(arr);//调用函数
b.所以应当在主函数内部求出arr大小并以参数的形式传入函数使用
(2) 然后进行函数调用和提示(找得到就打印提示与下标,找不到则只进行提示)
int ret=binary_search(arr,k,sz)
if(-1==ret)
printf("找不到指定数字呢");
else
printf("找到了哦,下标为%d",ret);
主函数部分告一段落
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;//要找的数
int sz = sizeof(arr) / sizeof(arr[0]) - 1;
int ret=binary_search(arr,k,sz);//传过去的是首元素的地址而不是数组
if (ret == -1)//找不到将返回-1
printf("找不到指定数字");
else
printf("找到了,下标为%d\n",ret);//找到了则返回下标
return 0;
}
自定义函数:
int binary_search(int arr[], int k,int sz)//函数的定义和实现
{
int left=0;
int right=sz-1;
int mid=(left+right)/2;//定义左右下标
while(left<=right)
{
int mid=(left+right)/2;//求出中间下标
if(k>arr[mid])//情况1:这个数大于目标数,说明目标数在这个数与左值(首元素)之间。那么就将这个数减一并赋给右下标。
{
right = mid - 1;
}
else if (arr[mid] < k)//情况2:这个数小于于目标数,目标数则在这个数与右值(末元素)之间。那么就将这个数加一并赋给左下标。
{
left = mid + 1;
}
else//情况3:两数刚好相等,那就直接找到了,返回下标即可
{
return mid;
}
}
注意:while的判断条件很重要,当left小于_等于_right时才能确保两端一直在向目标值汇聚而不遗漏(误漏等号)或“过头”。
完整代码:
int binary_search(int arr[], int k,int sz)//
{
int left = 0;
int right = sz-1;
while(left<=right)
{
int mid = (left + right) / 2;
if (arr[mid] > k)
{
right = mid - 1;
}
else if (arr[mid] < k)
{
left = mid + 1;
}
else
{
return mid;
}
}
return -1;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;//要找的数
int sz = sizeof(arr) / sizeof(arr[0]) ;
int ret=binary_search(arr,k,sz);//传过去的是首元素的地址而不是数组
if (ret == -1)
printf("找不到指定数字");
else
printf("找到了,下标为%d\n",ret);
return 0;
}
4.总结:
二分查找相比于逐个查找,极大地减小了时间复杂度,平均性能好,适合大数组中查找数据。但其缺点是要求待查表为有序表,且插入删除困难。
初次学习,若有遗漏或错误,感谢您的指正。