二分查找(Binary Search)是一种在有序数组中查找特定元素的搜索算法。它的工作原理是将数组分为两半,然后根据目标值与中间元素的关系,决定在左半部分还是右半部分继续搜索,直到找到目标值或者搜索范围为空。
二分查找算法的基本步骤如下:
1. 确定查找范围,初始时为整个数组。
2. 在查找范围内找到中间元素。
3. 比较中间元素与目标值:
- 如果中间元素等于目标值,则查找成功,返回中间元素的索引。
- 如果目标值小于中间元素,则在左半部分继续查找。
- 如果目标值大于中间元素,则在右半部分继续查找。
4. 重复步骤2和3,直到找到目标值或者查找范围为空。
二分查找的时间复杂度为 \( O(\log n) \),其中 \( n \) 是数组的长度。这是因为每次迭代可以将查找范围减少一半。
二分查找图解
一次干掉一半
前提是有序
折半查找
找一次,去掉一半
在有序的数字里,查找某一个数字
找到了
数值在左边
数值在右边
二分查找代码实现
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 }; int j = 0; scanf("%d", &j); int sz = sizeof(arr) / sizeof(arr[0]);//数组的总数,从1开始算 int left = 0;//左下标 int right = sz - 1;//减去1 才等于下标 这里是下标的意思 //int mid = (left + right) / 2; //不能给外面是因为此时没有进入循环 mid的数值是确定的 不会随着循环发生改变 while (left <= right) { int mid = (left + right) / 2; if (arr[mid] < j)//这里也就是如果中间值大的话 那实际输入的就小,可以再次循环排查 { left = mid + 1;//是因为中间值的不算进去的,然后既然已经 在else里面做排除所以加上会节约算法时间 } else if (arr[mid] > j) { right = mid - 1; } else if (arr[mid] == j) { printf("找到了,下标是:%d\n", mid); break; } else { printf("傻子仔细看看,没有这个数组"); break; } //printf("傻子仔细看看,没有这个数组"); //break; } /*printf("傻子仔细看看,没有这个数组");*/ return 0; }
解释:
#define _CRT_SECURE_NO_WARNINGS 1
:这行代码用于关闭微软编译器对于不安全函数(如scanf
)的警告。
#include<stdio.h>
:包含标准输入输出库,用于程序中的输入输出操作。
int main()
:程序的主入口点。
int arr[] = { 1,2,3,...,30 };
:定义一个整型数组arr
,并初始化为1到30的整数。
int j = 0;
:定义一个整型变量j
,用于存储用户输入的值。
scanf("%d", &j);
:通过标准输入读取用户输入的整数,并将其存储在变量j
中。
int sz = sizeof(arr) / sizeof(arr[0]);
:计算数组arr
的长度,即元素的总数。
int left = 0;
:定义变量left
作为二分查找的左边界。
int right = sz - 1;
:定义变量right
作为二分查找的右边界。
while (left <= right)
:开始一个循环,只要左边界不大于右边界,循环就会继续。
int mid = (left + right) / 2;
:计算中间索引mid
。
if (arr[mid] < j)
:如果中间元素小于j
,则将左边界更新为mid + 1
。
else if (arr[mid] > j)
:如果中间元素大于j
,则将右边界更新为mid - 1
。
else if (arr[mid] == j)
:如果中间元素等于j
,则找到了目标值,打印下标并退出循环。
else
:这个分支实际上永远不会执行,因为前面已经覆盖了所有可能的情况。
printf("找到了,下标是:%d\n", mid);
:如果找到目标值,打印其在数组中的下标。
break;
:退出循环。
printf("傻子仔细看看,没有这个数组");
:如果循环结束时没有找到目标值,打印这条消息。
return 0;
:程序正常结束。
二分查找注意事项
1,但是前提必粗是有序
2,二分查找,本质上是区间查找
3,尽量使用左闭右闭,这样前后一致就可以,简单的说就是当成下标来处理
二分查找时间复杂度