代码调优:二分搜索算法实践

开篇

本篇文章来源于对《编程珠玑》第9章:代码调优部分二分搜索方法的实现。

二分搜索–原始版本

伪代码

l = 0; u = n - 1;
loop
  if l > u
    p = -1;break;
  m = (l + u) / 2;
  else
    x[m] < t; l = m + 1;
    x[m] == t; p = m; break;
    x[m] > t; u = m - 1;

代码实现

// 二分搜索方法
int binarySearch(int x[], int n, int t) {
	int l = 0;
	int u = n - 1;
	int p = -1;

	while (l <= u) {
		int m = (l + u) / 2;

		if (x[m] < t) {
			l = m + 1;
		}
		else if(x[m] == t) {
			p = m;
			break;
		}
		else {
			u = m - 1;
		}
	}

	return p;
}

二分搜索 – 初步改动

伪代码

l = -1;u = n;
while l + 1!=u
  m = (l + u) / 2
  if x[m] < t
    l = m
   else
     u = m
   p = u
   if p >= n || x[p] != t
     p = -1

代码实现

// 二分搜索方法 -- 初步优化
int binarySearchPro(int x[], int n, int t) {
	int l = -1;
	int u = n;
	int p = -1;

	while (l + 1 != u) {
		int m = (l + u) / 2;

		if (x[m] < t) {
			l = m;
		}
		else {
			u = m;
		}
	}

	p = u;
	if (p >= n || x[p] != t) p = -1;

	return p;
}

二分搜索–再次改动

代码实现

// 二分搜索方法 -- 再次改动
// 这里利用了已知n=5这个条件,n为5的情况下,小于它的最大的2的幂为4
// 这里不再使用l...u来表示上下限值,而是用下限值l和增量i来表示,使得l+i=u
// 这种方法其实改动是微不足道的,且通用性较差
int binarySearchProPlus(int x[], int n, int t) {
	int i = 4;
	int l = -1;
	int p = -1;

	if (x[3] < t) l = 5 - 4;
	while (i != 1) {
		int nexti = i / 2;

		if (x[l + nexti] < t) {
			l = l + nexti;
			i = nexti;
		}
		else {
			i = nexti;
		}
	}

	p =  l + 1;
	if (p > 5 || x[p] != t) p = -1;

	return p;
}

总结

#include <stdio.h>

// 二分搜索方法
int binarySearch(int x[], int n, int t) {
	int l = 0;
	int u = n - 1;
	int p = -1;

	while (l <= u) {
		int m = (l + u) / 2;

		if (x[m] < t) {
			l = m + 1;
		}
		else if(x[m] == t) {
			p = m;
			break;
		}
		else {
			u = m - 1;
		}
	}

	return p;
}

// 二分搜索方法 -- 初步优化
int binarySearchPro(int x[], int n, int t) {
	int l = -1;
	int u = n;
	int p = -1;

	while (l + 1 != u) {
		int m = (l + u) / 2;

		if (x[m] < t) {
			l = m;
		}
		else {
			u = m;
		}
	}

	p = u;
	if (p >= n || x[p] != t) p = -1;

	return p;
}

// 二分搜索方法 -- 再次改动
// 这里利用了已知n=5这个条件,n为5的情况下,小于它的最大的2的幂为4
// 这里不再使用l...u来表示上下限值,而是用下限值l和增量i来表示,使得l+i=u
// 这种方法其实改动是微不足道的,且通用性较差
int binarySearchProPlus(int x[], int n, int t) {
	int i = 4;
	int l = -1;
	int p = -1;

	if (x[3] < t) l = 5 - 4;
	while (i != 1) {
		int nexti = i / 2;

		if (x[l + nexti] < t) {
			l = l + nexti;
			i = nexti;
		}
		else {
			i = nexti;
		}
	}

	p =  l + 1;
	if (p > 5 || x[p] != t) p = -1;

	return p;
}

int main() {
	int arr[] = { 2, 3, 4, 10, 40 };
	int n = sizeof(arr) / sizeof(arr[0]);
	int t = 10;

	int result = binarySearchProPlus(arr, n, t);

	if (result != -1) {
		printf("目标元素索引为 %d\n", result);
	}
	else {
		printf("目标元素不在数组内\n");
	}

	return 0;
}

其实上面代码改动带来的优化都不是很大,但这却能给人一种不同于原始版本的二分搜索实现思路,还是值得学习的。
希望本文能对您所有参考作用,感谢阅读!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值