.cpp
二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。
但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
//二分查找法
//二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。
//但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
//int main()
//{
// int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
// int count = sizeof(arr) / sizeof(arr[0]);
// int left = 0;
// int right = count - 1;
// int mid = 0;
// int k = 6;
// while (left<=right)
// {
// mid = ( right+left) / 2;
// if (arr[mid]<k)
// {
// left = mid+1;
// }
// else if(arr[mid] > k)
// {
// right = mid - 1;
// }
// else
// {
// printf("%d找到了,下标是%d\n",k,mid);
// break;
// }
// }
// if (left > right)
// {
// printf("%d找不到\n",k);
// }
// return 0;
//}
//思维模式:可以先写出这个函数怎么用,然后再创建函数并编写函数内容
int binary_search(int arr[],int k)
{
//算法的实现
int count = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = count - 1;
while (left <= right)
{
int mid = (right + left) / 2;
if (arr[mid] < k)
{
left = mid + 1;
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
return mid;
}
}
if (left > right)
{
return -1;
}
}
int main()
{
//如果找到了就返回这个数字的下标,找不到就返回-1
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;
int ret = binary_search(arr, k);
if (ret==-1)
{
printf("找不到指定的数字\n");
}
else
{
printf("找到了,下标是:%d\n", ret);
}
return 0;
}
上述代码中要查找的数字为7,运行结果为:
找不到指定的数字
D:\vs2019project\Cyuyan\Debug\Cyuyan.exe (进程 29152)已退出,代码为 0。
按任意键关闭此窗口. . .
由此可见,上述结果并非我们所想的那样,我们通过调试(Fn+F10,Fn+F11)可以看到,是函数里面的count(也就是数组的长度)出现了问题,调试窗口中count的值是1,但实际中count应为数组的长度10,这是为什么呢?
原来,我们知道数组名是数组首元素的地址,数组作为函数参数时,不会把整个数组传递过去,实际上是把数组的首元素地址传递过去了,既然上述代码中函数binary_search()可以接受我们传过去的数组元素的首地址,所以binary_search()里的arr本质上是一个指针,指针在32位平台上是4个字节,64位平台上是8个字节,此为32位平台,所以sizeof(arr)=4,又因为arr[0]为整型,即sizeof(arr[0])=4,所以count = sizeof(arr) / sizeof(arr[0])=1,这样我们就可以解释为什么count等于1了。
显然,在函数的内部计算数组的长度不是靠谱的,我们可以在函数的外部计算数组的长度,然后将它作为参数传入即可,代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
//二分查找法
//二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。
//但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
//int main()
//{
// int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
// int count = sizeof(arr) / sizeof(arr[0]);
// int left = 0;
// int right = count - 1;
// int mid = 0;
// int k = 6;
// while (left<=right)
// {
// mid = ( right+left) / 2;
// if (arr[mid]<k)
// {
// left = mid+1;
// }
// else if(arr[mid] > k)
// {
// right = mid - 1;
// }
// else
// {
// printf("%d找到了,下标是%d\n",k,mid);
// break;
// }
// }
// if (left > right)
// {
// printf("%d找不到\n",k);
// }
// return 0;
//}
//思维模式:可以先写出这个函数怎么用,然后再创建函数并编写函数内容
int binary_search(int arr[],int k,int count)
{
//算法的实现
int left = 0;
int right = count - 1;
while (left <= right)
{
int mid = (right + left) / 2;
if (arr[mid] < k)
{
left = mid + 1;
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
return mid;
}
}
if (left > right)
{
return -1;
}
}
int main()
{
//如果找到了就返回这个数字的下标,找不到就返回-1
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;
int count = sizeof(arr) / sizeof(arr[0]);
int ret = binary_search(arr, k,count);
if (ret==-1)
{
printf("找不到指定的数字\n");
}
else
{
printf("找到了,下标是:%d\n", ret);
}
return 0;
}
运行结果为:
找到了,下标是:6
D:\vs2019project\Cyuyan\Debug\Cyuyan.exe (进程 19236)已退出,代码为 0。
按任意键关闭此窗口. . .
这样就能运行成功了,欢迎批评指正。