二分查找

二分查找要求所查找的顺序表必须是有序的,其思想非常简单。定义left为顺序表最左端元素位置,right为顺序表右端元素位置。定义mid = (left + right) / 2,即顺序表的中间位置,然后用所查找的值与mid所在位置处的值比较,由于列表有序,若所查找的值比mid小,则只需在表的前半部分查找,否则只需在表的后半部分查找(若第一次比较就发现两值相等则直接返回当前值所在的位置),以此类推,直至查找到所寻找的值或确定所查找的值不在该列表内为止(即查找失败)。代码如下:

```c
#include<stdio.h>

int Binary_Search(int* a, int size, int val)
{
	int pos = -1;//pos返回查找到的值的位置
	if (a == nullptr || size < 1)//数组合法性检查
	{
		return pos;
	}
	int left = 0;
	int right = size - 1;
	while (left <= right)//当左端元素位置不等于右边元素位置时反复查找
	{
		int mid = (left + right) / 2;
		if (val < a[mid])//若所查找值小于中间值,在前半部分查找
		{
			right = mid - 1;
		}
		else if (val > a[mid])//若所查找值大于中间值在后半部分查找
		{
			left = mid + 1;
		}
		else
		{
			
			pos = mid;//若已找到则终止循环
			break;
		}
	}
	
	return pos;//返回查找到的值所在位置
}
int main()
{
	const int n = 10;
	int ar[n] = {12,23,34,45,56,67,78,89,90,100};
	int idex, value;
	printf("请输入要查询的值:");
	scanf_s("%d", &value);
	idex = Binary_Search(ar, n, value);//idex获取所查找的值得位置,即pos
	printf("%d", idex);//若idex = -1,要么数组不合法,要么查找失败。在数组合法的前提下即可知道查找失败
	return 0;
	}

那如果一个数组里有多个连续重复的值,我们想找到连续重复值中下标最小的应该怎么办呢?我们只需对else语句略作修改`

else
		{
			while (mid > left && a[mid - 1] == val)//在不越界的前提下后一个值与前一个值相等
			{
				--mid;//下标减一
			}
			pos = mid;//若已找到则终止循环
			break;
		}

完整代码如下:

#include<stdio.h>

int Binary_Search(int* a, int size, int val)
{
	int pos = -1;//pos返回查找到的值的位置
	if (a == nullptr || size < 1)//数组合法性检查
	{
		return pos;
	}
	int left = 0;
	int right = size - 1;
	while (left <= right)//当左端元素位置不等于右边元素位置时反复查找
	{
		int mid = (left + right) / 2;
		if (val < a[mid])//若所查找值小于中间值,在前半部分查找
		{
			right = mid - 1;
		}
		else if (val > a[mid])//若所查找值大于中间值在后半部分查找
		{
			left = mid + 1;
		}
		else
		{
			while (mid > left && a[mid - 1] == val)//在不越界的前提下后一个值与前一个值相等
			{
				--mid;//下标减一
			}
			pos = mid;//若已找到则终止循环
			break;
		}
	}
	
	return pos;//返回查找到的值所在位置
}
int main()
{
	const int n = 20;
	int ar[n] ={12,12,23,23,34,45,45,45,56,67,78,89,90,100,100,101 };
	int idex, value;
	printf("请输入要查询的值:");
	scanf_s("%d", &value);
	idex = Binary_Search(ar, n, value);//idex获取所查找的值得位置,即pos
	printf("%d", idex);//若idex = -1,要么数组不合法,要么查找失败。在数组合法的前提下即可知道查找失败
	
	return 0;
}
  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值