【数据结构与算法】二分查找

一.二分查找的原理

在这里插入图片描述
就是这个原理,跟中间的比的话,每次都可以排除一半.
上次在分治法里面我们用的递归实现,现在我们就普通的方法来实现.

二.二分查找的实现

为了能适应多种类型的查找,我们用到了函数指针做为参数.
这里我们写了int类型和char类型的比较.
相减来判断两个值的大小.
在这里插入图片描述
二分查找的参数:

  • 数组用的void*可以接受不同类型的数组
  • len是数组的长度
  • elemSize是元素的长度,因为void*类型的不能用下标访问,我们只能通过指针的相加去访问到目标数组元素,因为不同类型的数组,步长不一,需要传入这个.
  • search是查找目标
  • int (compare)(const voidkey1,const void*key2)是函数指针,传入不同的函数,指向不同的功能.

在这里插入图片描述
如果目标值等于中间的值,我们就返回这个下标,大于的话,左边的起始位置改变,小于的话,右边的位置改到中间位置的前一个.一直循环,直到left不小于right时.

在这里插入图片描述
在void*类型的数组中找目标元素的位置用的是指针加步长.就是字节的长度.
在这里插入图片描述

三.完整代码

#include <iostream>
using namespace std;

int int_compare(const void* key1, const void* key2)
{
	const int* ch1 = (const int*)key1;
	const int* ch2 = (const int*)key2;

	return (*ch1 - *ch2);
}

int char_compare(const void* key1, const void* key2)
{
	const char* ch1 = (const char*)key1;
	const char* ch2 = (const char*)key2;

	return (*ch1 - *ch2);
}


int BinarySearch(void* sorted, int len, int elemSize, void* search, int (*compare)(const void* key1, const void* key2))
{
	int left = 0, right = 0, middle = 0;
	right = len - 1;
	while (left<=right)
	{
		int ret = 0;
		middle = left + (right - left) / 2;
		ret = compare((char*)sorted + (middle * elemSize), search);
		if (ret == 0)
		{
			return middle;
		}
		else if (ret > 0)
		{
			right = middle - 1;
		}
		else
		{
			left = middle + 1;
		}
	}
	return -1;
}

int main()
{
	int arr[] = { 1,3,7,9,11 };
	int len = sizeof(arr) / sizeof(arr[0]);
	int search[] = { -1,0,1,7,2,11,12 };
	int lens = sizeof(search) / sizeof(search[0]);
	for (int i = 0; i < lens; i++)
	{
		int index = BinarySearch(arr, len, sizeof(int), &search[i], int_compare);
		printf("searching %d,index: %d\n", search[i], index);
	}

	printf("字符查找测试开始...\n");
	char arr1[] = { 'a','c','d','f','j' };
	char search1[] = { '0','a','e','j','z' };
	for (int i = 0; i < sizeof(search1) / sizeof(search1[0]); i++)
	{
		int index = BinarySearch(arr1, sizeof(arr1) / sizeof(arr1[0]), sizeof(char), &search1[i], char_compare);
		printf("searching %c,index: %d\n", search1[i], index);
	}

	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述
返回-1的就是没找到,其他的都是下标的位置.

2024年8月20日15:57:16

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值