有序向量二分查找算法-CPP实现(效率最高版本)

有序向量二分查找

 

目录

版本一

版本二

版本三

 

版本一

#include <iostream>
using namespace std;
template <typename T>
static int binSearch(T* A, T const& e, int lo, int hi)
{
	while (lo < hi)
	{
		int mi = (lo + hi) >> 1;
		if (e < A[mi])
		{
			hi = mi;
		}
		else if (e > A[mi])
		{
			lo = mi + 1;
		}
		else
		{
			return mi;
		}
	}
	return -1;
}

int main()
{
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
	int ret = binSearch<int>(arr, 5, 0, 10);
	cout << "ret = " << ret << endl;
	system("pause");
	return 0;
}

运行结果:

image-20221009184342707

缺点一:效率仍然可以优化,因为不难发现
转向左、右分支前的关键码比较次数不等,而递归深度却相同

缺点二:并未严格兑现search(e)接口"返回不大于e且秩最大的元素"的要求

1)当有多个命中元素时,必须返回最靠后者

2)失败时,应返回不大于(亦是小于)e的最大者

负无穷< e < V[lo]时,返回lo-1(左侧哨兵) V[hi-1] < e < 正无穷时,返回hi-1(右侧哨兵左邻)

返回目录

 

版本二

解决缺点一

#include <iostream>
using namespace std;
template <typename T>
static int binSearch(T* A, T const& e, int lo, int hi)
{
	while (hi - lo > 1)
	{
		int mi = (lo + hi) >> 1;
		(e < A[mi]) ? hi = mi : lo = mi;
	}
	return (e == A[lo]) ? lo : -1;
}

int main()
{
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
	int ret = binSearch<int>(arr, 5, 0, 10);
	cout << "ret = " << ret << endl;
	system("pause");
	return 0;
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o0bK9hcu-1665328780020)(C:\Users\Zhang\AppData\Roaming\Typora\typora-user-images\image-20221009224530122.png)]

如何更为精细地评估查找算法的性能?
考查关键码的比较次数,即查找长度(search length)

优点:此版本左、右分支前的关键码比较次数相等,最好情况下效率不如版本一; 作为补偿,最坏情况下效率有所提高
各种情况下的查找长度更加接近,整体性能更趋稳定

缺点:缺点二

返回目录

 

版本三

解决缺点一,缺点二

#include <iostream>
using namespace std;
template <typename T>
static int binSearch(T* A, T const& e, int lo, int hi)
{
	while (lo < hi)
	{
		int mid = (lo + hi) >> 1;
		(e < A[mid]) ? hi = mid : lo = mid + 1;
	}
	return --lo;
}

int main()
{
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
	int ret = binSearch<int>(arr, 5, 0, 10);
	cout << "ret = " << ret << endl;
	system("pause");
	return 0;
}

运行结果:

在这里插入图片描述

返回目录

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值