`
lony1107
  • 浏览: 7782 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

[转载 + 实现] 只有10%程序员能正确实现二分查找算法

阅读更多

在CSDN看到一篇题为《只有10%程序员能正确实现二分查找算法》的文章(原文链接http://news.csdn.net/a/20100423/218099.html),很有意思,在不进行测试的情况下,你能保证所写的二分查找是完全正确的吗?

 

只有10%的程序员可以写出二分查找

每次翻开《编程珠玑》,我都会先看一看下面这几段文字: 

二分查找可以解决(预排序数组的查找)问题:只要数组中包含T(即要查找的值),那么通过不断缩小包含T的范围,最终就可以找到它。一开始,范围覆盖整个数组。将数组的中间项与T进行比较,可以排除一半元素,范围缩小一半。就这样反复比较,反复缩小范围,最终就会在数组中找到T,或者确定原以为T所在的范围实际为空。对于包含N个元素的表,整个查找过程大约要经过log(2)N次比较。 
多数程序员都觉得只要理解了上面的描述,写出代码就不难了;但事实并非如此。如果你不认同这一点,最好的办法就是放下书本,自己动手写一写。试试吧。 
我在贝尔实验室和IBM的时候都出过这道考题。那些专业的程序员有几个小时的时间,可以用他们选择的语言把上面的描述写出来;写出高级伪代码也可以。考试结束后,差不多所有程序员都认为自己写出了正确的程序。于是,我们花了半个钟头来看他们编写的代码经过测试用例验证的结果。几次课,一百多人的结果相差无几:90%的程序员写的程序中有bug(我并不认为没有bug的代码就正确)。 
我很惊讶:在足够的时间内,只有大约10%的专业程序员可以把这个小程序写对。但写不对这个小程序的还不止这些人:高德纳在《计算机程序设计的艺术 第3卷 排序和查找》第6.2.1节的“历史与参考文献”部分指出,虽然早在1946年就有人将二分查找的方法公诸于世,但直到1962年才有人写出没有bug的二分查找程序。 
——乔恩·本特利,《编程珠玑(第1版)》第35-36页

 

自己也尝试了一下,没有用传说中好几个小时那么长的时间,也因慎重不是几分钟解决,在检查了一会儿,认为正确的情况下,代码如下:

 

private static int binarySearch(int[] sortedData, int targetValue) {
		return subBinarySearch(sortedData, 0, sortedData.length - 1,
				targetValue);
	}

	private static int subBinarySearch(int[] sortedData, int startIndex,
			int endIndex, int targetValue) {
		// 1 element
		if (startIndex == endIndex) {
			int onlyValue = sortedData[0];
			if (onlyValue == targetValue)
				return onlyValue;
			else
				return -1; // -1 indicates that target value is not found.
		}

		// 2 elements
		if (endIndex - startIndex == 1) {
			if (sortedData[startIndex] == targetValue)
				return startIndex;
			if (sortedData[endIndex] == targetValue)
				return endIndex;
			else
				return -1;
		}

		// 3 elements or more
		int middleIndex = (startIndex + endIndex) / 2;
		int middleValue = sortedData[middleIndex];
		if (middleValue == targetValue)
			return middleIndex;
		else if (middleValue > targetValue) {
			return subBinarySearch(sortedData, startIndex, middleIndex - 1,
					targetValue);
		} else { // if (middleValue < targetValue)
			return subBinarySearch(sortedData, middleIndex + 1, endIndex,
					targetValue);
		}
	}

 

自己进行了一些简单的测试,尚未发现错误,如果大家看到哪里有缺陷请指出来,非常感谢!欢迎交流!

分享到:
评论
1 楼 paradise2009 2013-10-25  
你的code有bug

int middleIndex = (startIndex + endIndex) / 2;  


这句有可能会超出int 65535的范围.

推荐写法:
int mid = lo + (hi - lo) / 2;


或者一个快速的通过位移实现的方法是:

int mid = (lo + hi) >>> 1; 


参考: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5045582

谢谢!

相关推荐

    90%程序员写不出无BUG的二分查找程序?.rar

    二分查找,也被称为折半查找,是一种在有序数组中搜索特定元素的高效算法。它以其高效的性能在计算机科学和编程领域中广受欢迎,尤其是在大数据处理和算法竞赛中。然而,尽管二分查找的原理相对简单,但在实际编程中...

    程序员实用算法 pdf+源码

    2. **查找算法**:如二分查找、哈希查找等。二分查找在有序数组中具有高效性,而哈希查找则利用哈希表实现快速定位,常用于大数据量的场景。 3. **数据结构**:包括链表、栈、队列、树(二叉树、平衡树如AVL树和...

    实现二分查找的完美算法 c++

    二分查找,也称为折半查找,是一种在有序数组中...理解并能熟练掌握二分查找算法对于任何IT专业人员来说都是非常重要的技能。同时,对于C++程序员来说,了解如何编写高效的C++代码来实现这种算法,有助于提升编程能力。

    数据结构查找、排序、二分查找、折半查找算法

    为提高查找效率,引入了二分查找算法。二分查找适用于已排序的数组或列表,通过不断将查找区间减半,直到找到目标元素或者确定不存在为止。它的优点在于时间复杂度为O(log n),远优于线性查找的O(n)。 接下来,我们...

    程序员面试算法大全

    3. **查找算法**:查找算法用于在数据集合中寻找特定元素,例如线性搜索、二分查找、哈希查找等。二分查找适用于有序数组,而哈希查找则在平均情况下具有较高的效率。 4. **图论与最短路径**:图论是解决网络问题和...

    程序员实用算法.zip

    2. **查找算法**:二分查找是常见的高效查找方法,适用于有序数组;哈希查找则通过散列函数快速定位数据,适用于大量数据的查找。此外,深度优先搜索(DFS)和广度优先搜索(BFS)是图和树结构中的经典查找策略。 3...

    程序员的算法趣题.pdf.zip

    二分查找是处理有序数据的有效方法,而哈希表则能实现快速查找。 3. **图论算法**:包括最短路径问题(Dijkstra算法、Floyd-Warshall算法)、最小生成树(Prim算法、Kruskal算法)等,这些都是解决网络优化问题的...

    王道程序员求职宝典+算法笔记

    在算法方面,书中的内容涵盖了基础数据结构如数组、链表、栈、队列,以及更复杂的结构如树(二叉树、平衡树)、图,还有排序和查找算法(冒泡排序、快速排序、二分查找、哈希查找等)。对于这些经典算法,书中不仅给...

    程序员算法趣题——随书源码

    1. **基础算法实现**:可能包括排序(如冒泡、快速、归并排序)、搜索(如二分查找、广度优先搜索、深度优先搜索)等经典的计算机科学算法。 2. **数据结构**:可能涉及到数组、链表、栈、队列、堆、树(二叉树、...

    程序员实用算法——sourceCode

    2. 查找算法:二分查找是一种在有序数组中查找元素的高效方法,其时间复杂度为O(log n)。哈希表则提供了快速的查找、插入和删除操作,适用于大量数据的管理。 3. 动态规划:这是一种解决最优化问题的策略,通过构建...

    程序员必备算法知识

    二分搜索在有序数组中查找元素时效率较高,而哈希表提供了一种快速查找和插入数据的方法,通过映射关系达到O(1)的时间复杂度。 3. **图论算法**:在处理网络结构或复杂关系时,图论算法显得尤为重要。例如,深度...

    程序员算法面试笔试大全下载

    常见的算法包括排序(冒泡排序、选择排序、插入排序、快速排序、归并排序等)、查找(线性查找、二分查找、哈希查找)、图算法(深度优先搜索、广度优先搜索、Dijkstra算法、Floyd算法)、字符串匹配(KMP算法、...

    Java常用排序算法&程序员必须掌握的8大排序算法+二分法查找

    综上所述,掌握这些排序算法和二分查找技巧对于Java程序员来说至关重要,它们不仅能提升编程能力,也有助于解决实际问题,提高代码的运行效率。通过学习和实践,你将能够更好地应对各种编程挑战。

    程序员实用算法

    2. **查找算法**:二分查找、哈希查找、线性查找等是常见的查找算法。二分查找适用于有序数据,其效率远高于线性查找;哈希查找通过键值映射实现快速定位,但需要合理设计哈希函数以避免冲突。 3. **图论与网络流**...

    程序员实用算法书中的源码

    1. **排序与查找算法**:书中可能包含了快速排序、归并排序、插入排序、二分查找、哈希表查找等多种排序和查找算法的源码实现。这些基础算法是任何程序员必备的技能,对于数据处理和优化性能至关重要。 2. **图论与...

    程序员实用算法.pdf

    - 二分查找:适用于有序数组,时间复杂度为O(log n)。 - 哈希表查找:通过哈希函数快速定位数据,查找速度快,但可能有冲突问题。 3. **图算法**: - Dijkstra算法:用于求解单源最短路径问题。 - Bellman-Ford...

    程序员面试经典算法题

    2. **搜索算法**:二分查找、深度优先搜索(DFS)、广度优先搜索(BFS)等,这些算法在解决寻找问题时非常有效。了解它们的工作原理和优化技巧,能够快速定位和解决问题。 3. **图论问题**:最短路径问题(如...

    《程序员实用算法》(高清全本)

    其次,搜索算法也是必不可少的部分,例如二分查找、深度优先搜索(DFS)和广度优先搜索(BFS)。这些算法在数据检索、图论问题中发挥着重要作用。二分查找适用于有序数组,而DFS和BFS则常用于遍历树形结构或图结构。...

    C#基础查找算法的分析,实现

    总的来说,理解并掌握查找算法对于C#程序员来说是必不可少的技能。通过学习和实践这些基础查找算法,我们可以更好地应对各种数据处理挑战,提高程序的运行效率。同时,这也为进一步学习更复杂的算法,如哈希查找、B...

Global site tag (gtag.js) - Google Analytics