关于二分法查找的问题

【题目要求】在给定的有序数组中,查找一个给定的val的值,返回它的位置。

【循环实现】:

int BinaryFind(int *arr, int n, int val)

{
	int pos = -1;
	if (arr == NULL || n < 1)
		return pos;
	int left = 0, right = n - 1;
	while (left <= right)
	{
		//int mid = (left + right) / 2;//可能超过最大整数。2147483647
		int mid = (right - left + 1) / 2  + left;
		if (arr[mid] > val)
		{
			right = mid - 1;
		}
		else if (arr[mid] < val)
		{
			left = mid + 1;
		}
		else
		{
			pos = mid;
			/*
			//找最左边
			while (arr[pos - 1] == val && pos >= 0)
				pos--;
			//找最右边
			while (arr[pos + 1] == val && pos != n)
				pos++;
				*/
			break;
		}
	}
	return pos;
}

【部分代码解读】:

1,//int mid = (left + right) / 2;//可能超过最大整数。2147483647
        int mid = (right - left + 1) / 2  + left;

相信一般第一次想到求中间位置,人们惯性的就想到了 int mid = (left + right )/2这种求法。
但是当数组的个数很大的时候就会出现问题,,,比如我们这里采用的整型数组,那么

当数据个数为21亿的时候,比如要查找的数据在数组靠近末尾的位置,那么我们在某次left + right 就有可能大于int的最大值而,或越界为负数,或越界为正数。那么结果可想而知就出错了。

我们采用int mid = (right - left + 1)/2 + left 可以在一定程度上避免这中情况的发生。增强了程序的健壮性。

2,

/*
			//找最左边
			while (arr[pos - 1] == val && pos >= 0)
				pos--;
			//找最右边
			while (arr[pos + 1] == val && pos != n)
				pos++;
				*/

当有多个重复的值的时候可以打开注释代码,选择获取val的最左边,或者最右边的位置。 

【代码,返回找到位置的地址】

//用指针来实现返回地址
int *FindValue(int *left, int *right, int val)
{
	if (left == NULL || right == NULL)
	{
		return NULL;
	}
	int *middle = NULL;
	while (left <= right)
	{
		middle = left + (right - left + 1) / 2;
		if (*middle < val)
		{
			left = middle + 1;
		}
		else if (*middle > val)
		{
			right = middle - 1;
		}
		else return middle;
	}
	return NULL;
}

【用递归来实现】

int Search(int *arr, int left, int right, int val)
{
	int mid = (right - left + 1) / 2 + left;//防止超过int最大值,用这种方法比较号。。。。
	if (left > right)
	{
		return -1;
	}
	if (arr[mid] < val)
		return Search(arr, mid + 1, right, val);
	else if (arr[mid] > val)
		return Search(arr, left, mid - 1, val);
	else
	{
		while (arr[mid - 1] == val && mid >= 0)
			mid--;
		return mid;
	}
}

【解读】:

while (arr[mid - 1] == val && mid >= 0)
			mid--;

这段的目的是为了返回最左边的val的位置。

猜你喜欢

转载自blog.csdn.net/qq_42418668/article/details/89410345