数组之二分查找
有这样一道题目:在一个升序的数组中查找指定的数字n,我们最先想到的就是遍历数组:
1.遍历法
假设有一个数组存储数字1–10,我们要查找指定的数字9。
我们先来了解一下数组的一些性质:
①C语言中规定数组是有下标的,下标从0开始。假定数组有n个元素,最后一个元素的下标就是n-1.例如:
int arr[10]={1,2,3,4,5,6,7,8,9,10};
数组随下标的增长,地址是由小到大变化的,数组在内存中是连续存放的。
②计算元素大小、计算元素个数
int a = sizeof(arr[0]);//计算元素大小
int sz = sizeof(arr)/sizeof(arr[0]);//计算数组的元素个数
遍历法代码示例如下:
找数字--遍历法
int main()
{
char arr[] = {1,2,3,4,5,6,7,8,9,10};
int k = 9;//在数组中找数字9
int i = 0;
int flag = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
if (k == arr[i])
{
printf("找到了,下标为%d", i);
flag = 1;
break;
}
}
if (flag == 0)
printf("没找到");
return 0;
}
2.二分查找
二分查找,也就是折半查找。比如说我让你猜一个数字,范围在1–100之间,如果1、2、3…99、100依次去猜显然太浪费时间,那我们就可以先猜个中间值150,如果大了,那么150之后的数字全部被舍弃,数字的范围就在1–150之间,然后我们继续猜中间值…依次进行下去,这种方法的时间效率比遍历快得多。图解如下:
二分查找法代码示例如下:
#include <stdio.h>
int main()
{
char arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 9;//在数组中找数字9
int i = 0;
int flag = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = sz - 1;
while (left <= right)
{
int mid = (left + right) / 2;//如果数字非常大,可能会超出整型的范围
if (k > arr[mid])
{
left = mid + 1;
}
else if (k < arr[mid])
{
right = mid - 1;
}
else
{
flag = 1;
printf("找到了,下标为%d\n", mid);
break;
}
}
if (flag == 0)
{
printf("找不到了");
}
}
在上述代码中,求中间元素的下标使用 mid=(left+right)/2,如果left和right都很大时,有可能超出整型范围,我们可以使用 mid = left + (right - left) / 2
int main()
{
char arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 9;//在数组中找数字9
int i = 0;
int flag = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = sz - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (k > arr[mid])
{
left = mid + 1;
}
else if (k < arr[mid])
{
right = mid - 1;
}
else
{
flag = 1;
printf("找到了,下标为%d\n", mid);
break;
}
}
if (flag == 0)
{
printf("找不到了");
}
}
本期结束,别忘了点赞关注收藏哦~~