算法:二分查找(折半查找)

二分查找:
在一个有序的序列中,找某个数据是否在该集合中,如果在打印该数据在集合中的下标,否则打印找不到

具体找的方式:

  1. 找到数组的中间位置
  2. 检测中间位置的数据是否与要查找的数据key相等
    a: 相等,找到,打印下标,跳出循环
    b: key < arr[mid], 则key可能在arr[mid]的左半侧,继续到左半侧进行二分查找
    c: key > arr[mid], 则key可能在arr[mid]的右半侧,继续到右半侧进行二分查找

如果找到返回下标,否则继续,直到区间中没有元素时,说明key不在集合中,打印找不到

易错点:

  1. right的右半侧区间取值,该值决定了后序的写法

  2. while循环的条件是否有等号

  3. 求中间位置的方法,直接相加除2容易造成溢出
    方法a
    int mid = (right + left) / 2;
    方法b 对两个数取中间即平均分配多出来的一部分
    int mid = left + (right - left) / 2;
    方法c 利用了计算机的计算特性:&求出两部分一样的;^求出两部分不同的;>>右移一位即除以2;
    int mid = (left & right) | ((left ^ right) >> 1);

  4. 更改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;
}

猜你喜欢

转载自blog.csdn.net/Sober_harmonic/article/details/117025307