文章目录
前言
一、什么是二分查找?
二分查找也称折半查找,是在一组有序(升序或者降序)的数据中查找一个元素,它是一种很高效的的查找方法。
二、二分查找的原理
注意:查找的数据必须是有序的,不然就没有意义了。
二分查找的基本原理如下:
1、确定要查找区间的左右端点 left 和 right;
2、计算中间位置 mid = (left + right) / 2;
3、比较中间位置 mid 的值和要查找的目标值 target:
(1)如果 mid 的值等于目标值 target,则找到了目标值;
(2)如果 mid 的值大于目标值 target,则在左半边的区间 [left, mid-1] 继续查找;
(3)如果 mid 的值小于目标值 target,则在右半边的区间 [mid+1, right] 继续查找;
4、重复上述步骤,直到找到目标元素或者区间不存在为止。
简单来说就是每次找到区间的中位数,判断该中位数是否是目标值,若不是则确定新的区间范围再寻找其中位数。以此类推,直到找到目标值为止。
三、数组长度的奇偶性对其的影响
我们以升序为列进行解释,降序方法类似
1.当数组是的长度是奇数时:
假设有一组数组是:arr[]={1,2,3,4,5},
中间数字的下标是:(0+4)/2=2;
元素是:3
要查找的数是:4
由图可知:我们要查找的数大于中间元素,所以中间元素的 左边的元素全部舍弃
2.当数组的长度是偶数时:
假设有一组数组是:arr[]={1,2,3,4,5,6},
中间数字的下标是:(0+5)/2=2.5;
元素是:3
当我们的 中间数字的下标是小数时,又该怎样取值呢?其实这个时候我们只需要向下取整或者向上取整就行了,不过一般都是采用的是向下取整
其实数组的长度其实对我们查找没有太大的关系
四、实现过程
在数组arr[]={1,2,3,4,5}
查找元素:4
图中“排除左边的元素”是指“排除mid左边的元素”
那如果我们查找一个不在数组以内的数呢?
比如我们查找:6
五、代码实现
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int Reach(int arr[], int sz, int k)
{ //int arr[]是数组,int sz是数组的长度,int k是查找的数值
int left = 0;//定义左下标
int right = sz - 1;///定义右下标
while (left <= right)
{
int mid = (left + right) / 2;
if (arr[mid] < k)
{
left = mid+ 1;;
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
return mid;
}
}
return -1;//没有找到要查找的数值
}
int main()
{
int n;
scanf("%d", &n);//要查找的元素
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int ret=Reach(arr, sz, n);
if (ret == -1)
{
printf("没有找到\n");
}
else
{
printf("下标是:%d\n", ret);
}
return 0;
}
1.顺序查找与二分查找的区别
这是顺序查找
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int n;
scanf("%d", &n);
for (int i = 0; i < sz; i++)
{
if (arr[i] == n)
{
printf("找到了啦!下标是:%d\n", i);
break;
}
if (i == sz-1)
{
printf("没有找到\n");
}
}
return 0;
}
虽然顺序查找在书写上要比二分查找要简便点,但是二分查找的速度要比顺序 查找要快,两者在查找之前,必须知道要查找的”值",查找目的都是该”值“在列表中所在的位置(下标)
六、二分查找的优缺点
1.优点:
二分查找算法的优点是比较次数少,查找速度快,平均性能好。这使得二分查找算法在查找特定元素时非常高效。
2. 缺点:
二分查找算法的缺点是需要有序数组。这意味着在使用二分查找算法之前,需要先对数组进行排序。而在排序过程中,数组的插入和删除效率是较低的,这就降低了二分法的性能。解决这个问题的方法是使用平衡二叉树。
此外,二分查找算法的实现方式主要有两种,一种是递归实现,另一种是循环实现。在实际应用中,可以根据具体情况选择适合的实现方式。