在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);
}
}
自己进行了一些简单的测试,尚未发现错误,如果大家看到哪里有缺陷请指出来,非常感谢!欢迎交流!
分享到:
相关推荐
二分查找,也被称为折半查找,是一种在有序数组中搜索特定元素的高效算法。它以其高效的性能在计算机科学和编程领域中广受欢迎,尤其是在大数据处理和算法竞赛中。然而,尽管二分查找的原理相对简单,但在实际编程中...
2. **查找算法**:如二分查找、哈希查找等。二分查找在有序数组中具有高效性,而哈希查找则利用哈希表实现快速定位,常用于大数据量的场景。 3. **数据结构**:包括链表、栈、队列、树(二叉树、平衡树如AVL树和...
二分查找,也称为折半查找,是一种在有序数组中...理解并能熟练掌握二分查找算法对于任何IT专业人员来说都是非常重要的技能。同时,对于C++程序员来说,了解如何编写高效的C++代码来实现这种算法,有助于提升编程能力。
为提高查找效率,引入了二分查找算法。二分查找适用于已排序的数组或列表,通过不断将查找区间减半,直到找到目标元素或者确定不存在为止。它的优点在于时间复杂度为O(log n),远优于线性查找的O(n)。 接下来,我们...
3. **查找算法**:查找算法用于在数据集合中寻找特定元素,例如线性搜索、二分查找、哈希查找等。二分查找适用于有序数组,而哈希查找则在平均情况下具有较高的效率。 4. **图论与最短路径**:图论是解决网络问题和...
2. **查找算法**:二分查找是常见的高效查找方法,适用于有序数组;哈希查找则通过散列函数快速定位数据,适用于大量数据的查找。此外,深度优先搜索(DFS)和广度优先搜索(BFS)是图和树结构中的经典查找策略。 3...
二分查找是处理有序数据的有效方法,而哈希表则能实现快速查找。 3. **图论算法**:包括最短路径问题(Dijkstra算法、Floyd-Warshall算法)、最小生成树(Prim算法、Kruskal算法)等,这些都是解决网络优化问题的...
在算法方面,书中的内容涵盖了基础数据结构如数组、链表、栈、队列,以及更复杂的结构如树(二叉树、平衡树)、图,还有排序和查找算法(冒泡排序、快速排序、二分查找、哈希查找等)。对于这些经典算法,书中不仅给...
1. **基础算法实现**:可能包括排序(如冒泡、快速、归并排序)、搜索(如二分查找、广度优先搜索、深度优先搜索)等经典的计算机科学算法。 2. **数据结构**:可能涉及到数组、链表、栈、队列、堆、树(二叉树、...
2. 查找算法:二分查找是一种在有序数组中查找元素的高效方法,其时间复杂度为O(log n)。哈希表则提供了快速的查找、插入和删除操作,适用于大量数据的管理。 3. 动态规划:这是一种解决最优化问题的策略,通过构建...
二分搜索在有序数组中查找元素时效率较高,而哈希表提供了一种快速查找和插入数据的方法,通过映射关系达到O(1)的时间复杂度。 3. **图论算法**:在处理网络结构或复杂关系时,图论算法显得尤为重要。例如,深度...
常见的算法包括排序(冒泡排序、选择排序、插入排序、快速排序、归并排序等)、查找(线性查找、二分查找、哈希查找)、图算法(深度优先搜索、广度优先搜索、Dijkstra算法、Floyd算法)、字符串匹配(KMP算法、...
综上所述,掌握这些排序算法和二分查找技巧对于Java程序员来说至关重要,它们不仅能提升编程能力,也有助于解决实际问题,提高代码的运行效率。通过学习和实践,你将能够更好地应对各种编程挑战。
2. **查找算法**:二分查找、哈希查找、线性查找等是常见的查找算法。二分查找适用于有序数据,其效率远高于线性查找;哈希查找通过键值映射实现快速定位,但需要合理设计哈希函数以避免冲突。 3. **图论与网络流**...
1. **排序与查找算法**:书中可能包含了快速排序、归并排序、插入排序、二分查找、哈希表查找等多种排序和查找算法的源码实现。这些基础算法是任何程序员必备的技能,对于数据处理和优化性能至关重要。 2. **图论与...
- 二分查找:适用于有序数组,时间复杂度为O(log n)。 - 哈希表查找:通过哈希函数快速定位数据,查找速度快,但可能有冲突问题。 3. **图算法**: - Dijkstra算法:用于求解单源最短路径问题。 - Bellman-Ford...
2. **搜索算法**:二分查找、深度优先搜索(DFS)、广度优先搜索(BFS)等,这些算法在解决寻找问题时非常有效。了解它们的工作原理和优化技巧,能够快速定位和解决问题。 3. **图论问题**:最短路径问题(如...
其次,搜索算法也是必不可少的部分,例如二分查找、深度优先搜索(DFS)和广度优先搜索(BFS)。这些算法在数据检索、图论问题中发挥着重要作用。二分查找适用于有序数组,而DFS和BFS则常用于遍历树形结构或图结构。...
总的来说,理解并掌握查找算法对于C#程序员来说是必不可少的技能。通过学习和实践这些基础查找算法,我们可以更好地应对各种数据处理挑战,提高程序的运行效率。同时,这也为进一步学习更复杂的算法,如哈希查找、B...