C语言函数二分查找(折半查找)

2023-05-12 20:57:52 浏览数 (1)

C语言函数二分查找(折半查找)

参考视频讲解哔哩哔哩比特鹏哥的视频 ——链接

代码语言:javascript复制
二分查找
#include <stdio.h>

	//二分查找
   //在一个有序数组中查找具体的某个数
	//如果找到了返回,这个数的下标,找不到返回-1

	//例如我要在这个数组中找到7
	//首先找到这组被查找元素的中间的元素
	//假如说发现中间元素5要比我要找的数要小
	//说明我要找的数在5的右边,这样我的范围就缩小了一半
	//查找了一次范围就缩小了一半,这样的速度是比较快的
	//这就叫二分查找(折半查找)
	//那么怎么找到中间元素的下标呢
	//原来的数组是1 2 3 4 5 6 7 8 9 10 
	//他们的下标是0 1 2 3 4 5 6 7 8 9
	//左下标为0,右下标为9
	//给定完这组元素的下标,就可以通过左右元素的下标来确定中间元素的下标
	//就是这组被查找元素的左下标是0,右下标是9
	//0和9的平均值是4,下标4锁定的元素是5,就可以认为5就是这组元素的中间元素了
	//5这个元素比我要找的7要小
	//说明我要被查找的元素范围就变成了6到10
	//新的范围,左下标是5,右下标是9
	//左右下标又可以求出一个平均值是7,又找到一个对应的元素是8
	//所以这一组查找范围的中间元素是8
	//用8再跟我要找的元素比一下,比我找的元素要大
	//说明我要查找的元素在8的左边
	//这时候要查找的范围被再次的缩小成了6到7


	//基本思想,当我确定了被查找范围时候,要确定他的左下标和右下标,然后求出下标的平均值,
	//找到中间元素,将中间元素和我要找的元素比一下,如果比我找的元素大,说明我要找的元素在他的左边,
	//如果比我要找的元素小,说明我要找的元素在他的右边,
	//这样确定出新的范围,出现新的左右下标。
	//一直找到左右下标无法确定新的范围,他们之间没有元素可以被查找的时候,结束,说明没有找到
	//如果在某一次查找的时候,找到了,下标相等了,说明找到了,把下标给过来

int number_search(int arr[], int k)
{
	//算法实现
	int sz = sizeof(arr) / sizeof(arr[0]);
	int left = 0;//左下标
	int right = sz - 1 ;//右下标
	//放到循环中
	while (left <= right)//这样才说明中间是有元素可以被查找的
	{
		int mid = (right   left) / 2;//中间元素的下标
		//拿到这个mid——锁定个元素
		if (arr[mid] < k)//如果中间元素比我要找的k要小,
						//被查找范围的右下标不用变,左下标变成mid !
		{
			left = mid   1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			return mid;
		}
		//如果找不到
		return -1;//返回去了
	}
}


int main(void)
{
	
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;
	int ret = number_search(arr, k);
	if (ret == -1)
	{
		printf("找不到指定的数字n");
	}
	else
	{
		printf("找到了,下标是:%dn",ret);
	}
	return 0;
}

//运行发现找不到结果——代码出现了问题
//自己找问题的方法
代码语言:javascript复制
//部分位置添加注释后
 二分查找
#include <stdio.h>

int number_search(int arr[], int k)
//实际上这地方传递过来的数组arr是首元素地址
//本质上这里的arr是个指针,因为指针才可以接收地址
{
	//算法实现
	int sz = sizeof(arr) / sizeof(arr[0]);
	// 4/4=1  无法得到元素个数
	//sz出现了问题
	int left = 0;//左下标
	int right = sz - 1;//右下标
	//放到循环中
	while (left <= right)//这样才说明中间是有元素可以被查找的
	{
		int mid = (right   left) / 2;//中间元素的下标
		//拿到这个mid——锁定个元素
		if (arr[mid] < k)//如果中间元素比我要找的k要小,
						//被查找范围的右下标不用变,左下标变成mid !
		{
			left = mid   1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			return mid;
		}
		//如果找不到
		return -1;//返回去了
	}
}


int main(void)
{

	int arr[] = {1,2,3,4,5,6,7,8,9,10};
	int k = 7;
	//只要把数组传参传过去
	//在内部是不能再上面的方式求元素个数了
	//数组是一块连续的空间,他里面可以放很多个元素
	//数组在传参的时候
	int ret = number_search(arr, k);//在这里仅仅传的是数组第一个元素的地址,不是所有元素
	if (ret == -1)
	{
		printf("找不到指定的数字n");
	}
	else
	{
		printf("找到了,下标是:%dn", ret);
	}
	return 0;
}

既然传进去不行,那就在外面算,

代码语言:javascript复制
//修改版(注释已经删除)(只有修改后的注释)
二分查找
#include <stdio.h>
//将多传递过来的参数sz接收
int number_search(int arr[], int k,int sz)
{
	int left = 0;
	int right = sz - 1 ;	
    //进入到这个循环中就是一次二分查找
    //在这里要进行很多次
    //每一次二分查找的第一步是找被查找范围的中间元素的下标
	while (left <= right)
	{
		int mid = (right   left) / 2;
		if (arr[mid] < k)
		{
			left = mid   1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			return mid;
		}
	}
    return -1;
}
int main(void)
{	
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;
    //将计算元素个个数
    int sz = sizeof(arr) / sizeof(arr[0]);
	int ret = number_search(arr, k,sz);//将sz也传过去
	if (ret == -1)
	{
		printf("找不到指定的数字n");
	}
	else
	{
		printf("找到了,下标是:%dn",ret);
	}
	return 0;
}

正在学习ing

0 人点赞