二分查找:
在一个有序的序列中,找某个数据是否在该集合中,如果在打印该数据在集合中的下标,否则打印找不到
具体找的方式:
- 找到数组的中间位置
- 检测中间位置的数据是否与要查找的数据key相等
a: 相等,找到,打印下标,跳出循环
b: key < arr[mid], 则key可能在arr[mid]的左半侧,继续到左半侧进行二分查找
c: key > arr[mid], 则key可能在arr[mid]的右半侧,继续到右半侧进行二分查找
如果找到返回下标,否则继续,直到区间中没有元素时,说明key不在集合中,打印找不到
易错点:
-
right的右半侧区间取值,该值决定了后序的写法
-
while循环的条件是否有等号
-
求中间位置的方法,直接相加除2容易造成溢出
方法a
int mid = (right + left) / 2;
方法b 对两个数取中间即平均分配多出来的一部分
int mid = left + (right - left) / 2;
方法c 利用了计算机的计算特性:&求出两部分一样的;^求出两部分不同的;>>右移一位即除以2;
int mid = (left & right) | ((left ^ right) >> 1);
-
更改left和right的边界时,不确定是否要+1和-1
//编写代码在一个整形有序数组中查找具体的某个数
//要求:找到了就打印数字所在的下标,找不到则输出:找不到。
#include<stdio.h>
#include<Windows.h>
#pragma warning(disable:4996)
int BinSearch(int arr[], int size, int num)
{
int left = 0;
int right = size - 1;
while (left <= right)
{
int mid = (left&right) | ((left^right) >> 1);
if (num < arr[mid])
{
right = mid - 1;
}
else if (num>arr[mid])
{
left = mid + 1;
}
else
{
return mid;
}
}
return -1;
}
int main()
{
int arr[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
printf("请输入需要查找的数:");
int num = 0;
scanf("%d", &num);
int size = sizeof(arr) / sizeof(arr[0]);
int x = BinSearch(arr, size, num);
if (x == -1)
{
printf("找不到\n");
}
else
{
printf("该数字在数组的下标是:%d\n", x);
}
system("pause");
return 0;
}