折半查找——多方法实现

折半查找四要素:

  1. 查找的内容必须是有序的(升序/降序);
  2. 每次查找都必须先锁定中间元素;
  3. 需要查找的元素与中间元素进行比较,从而缩小查找范围;
  4. 当左下标等于右下标时还未找到,说明要查找的元素不再给定的范围内。

实现整型有序数组的二分查找。(假设需要在整型有序数组 arr[ ] = { 1,2,3,4,5,6,7,8,9,10 } 中查找元素 " 7 " )

简体思路:首先定义一个整型有序数组;然后确定需要查找的元素;再锁定中间元素;用中间元素 与 要查找的元素进行比较,确定要查找的元素所在的范围;改变 左(右)下标,重新锁定中间元素,继续比较,直到 左下标 等于 右下标;如果此时找到了,就返回中间元素下标,如果没找到,说明要查找的元素不再给定范围内。
方法一:
普通代码实现:

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };	// 定义整型有序数组
	int key = 7;	// 确定要查找的元素
	int left = 0;	// 数组元素左下标
	int mid = 0;
	int right = sizeof(arr) / sizeof(arr[0]) - 1;	// 数组元素右下标

	// 当 左下标 <= 右下标 时进行查找
	while (left <= right) {
		mid = (left + right) / 2;	// 锁定中间元素

		// 如果 中间元素 > 要查找的元素,说明要查找的元素在 中间元素的左边,
		// 把 右下标 换为 中间元素的 下标减一
		if (arr[mid] > key) {
			right = mid - 1;
		}
		
		// 如果中间元素 < 要查找的元素,说明要查找的元素在 中间元素的右边,
		//把 左下标 换为 中间元素的 下标加一
		else if (arr[mid] < key) {
			left = mid + 1;
		}
	
		// 否则退出循环
		else {
			break;
		}
	}

	// 如果 左下标 <= 右下标 退出,则表示找到了,输出下标
	if (left <= right) {
		printf("\n找到了,下标是:%d\n", mid);
	}

	// 如果 左下标 > 右下标 退出,表示找不到。
	else {
		printf("找不到\n");
	}
	
	system("pause");
	return 0;
}

代码执行结果:
在这里插入图片描述
方法二:
函数实现二分查找。
代码实现:

#include<stdio.h>
#include<stdlib.h>

// 定义 bainary_search 二分查找函数
// 参数:int arr[] --> 整型有序数组
//	    int k --> 需要查找的元素
//	    int sz --> 数组大小
int binary_search(int arr[], int k, int sz)
{
	int left = 0;
	int right = sz;

	// 如果 左下标 <= 右下标,则进行比较
	while (left <= right) {

		int mid = (left + right) / 2;	// 锁定中间元素

		// 中间元素 与 要查找的元素 进行比较
		if (arr[mid] > k)	
		{	
			right = mid - 1;	//如果中间元素大于要查找的元素,改变右下标
		}
		else if (arr[mid] == k) 
		{
			return mid;			//如果中间元素等于要查找的元素,返回中间元素下标
		}
		else {
			left = mid + 1;		//如果中间元素小于要查找的元素,改变左下标
		}
	}
  // 当 左下标 > 右下标 时返回 -1
	return -1;
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]) - 1;	// 数组总大小
	int ret = binary_search(arr, 7, sz);		// 调用函数,接收函数返回值
	if(ret == -1)
	{
		printf("找不到\n");
	}
	else {
	printf("找到了,下标是:%d\n", ret);
	}
	system("pause");
	return 0;
}

代码执行结果:
在这里插入图片描述
注意事项:
1、函数传参时,如果参数是数组,则一定要记住,传过去的是数组首元素的地址。如果函数内部需要用到数组长度,则必须在函数外部计算好该数组的长度,然后以整型进行传参。
2、我们知道,计算两个整型数字的平均数时可以用 这两个数之和除以 2 得到,在计算机中这个方法虽然可行,但当这两个整型数字特别大时,这两个数相加就会出现越界,也就会丢失部分精度,从而造成结果的错误。所以我们可以采用其他的方法求两个数的平均数。
如:较小的数 + (较大的数 - 较小的数)/ 2

对上面锁定中间元素代码改进:

int mid = left + (right - left) / 2;	// 改进锁定中间元素
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值