欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-17 14:52:34
...

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

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

二分查找
#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("找到了,下标是:%d\n",ret);
	}
	return 0;
}

//运行发现找不到结果——代码出现了问题
//自己找问题的方法
//部分位置添加注释后
 二分查找
#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("找到了,下标是:%d\n", ret);
	}
	return 0;
}

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

//修改版(注释已经删除)(只有修改后的注释)
二分查找
#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("找到了,下标是:%d\n",ret);
	}
	return 0;
}

正在学习ing