在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);
}
}
自己进行了一些简单的测试,尚未发现错误,如果大家看到哪里有缺陷请指出来,非常感谢!欢迎交流!
分享到:
相关推荐
二分法数据查找C语言实现,只有10%程序员能正确实现二分查找算法--http://news.csdn.net/a/20100423/218099.html
二分查找算法是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素...
C++二分查找、插值查找、斐波那契查找对比C++的实现源码,不是完整程序,仅是核心算法文件 想要跑起来 自己要懂得动动手咯
快速排序算法 堆排序算法 归并排序 二分查找算法 BFPRT(线性查找算法) DFS(深度优先搜索) BFS(广度优先搜索) Dijkstra算法 动态规划算法 朴素贝叶斯分类算法
《算法导论》是一本好书,但是他太难了,就算是现在的我,再不借助资料的情况下,也绝看不...超四十种常见算法思想:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法。
能学到什么:掌握二分查找算法的实现原理;了解双指针技巧在数组问题中如何应用;学习算法代码的编写方法。 阅读建议:仔细理解题目要求,分析清楚算法思路才开始编程;可以边学习参考代码,边自己实现对应算法。对比输出...
例如,二分搜索可以用于在一个有序整数数组中查找特定的整数。使用二分搜索,我们可以通过不断将数组分为两部分,判断目标元素在哪一部分,然后在该部分继续进行二分搜索,直到找到目标元素或确定目标元素不存在。 ...
150个编程题问答从二叉树到二分查找,该部分涵盖了关于数据结构和算法的最常见、最有用的面试题以及最为精巧的解决方案。应对棘手算法题的5种行之有效的方法通过这5种方法,你可以学会如何处理并攻克算法难题,包括...
稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题...程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、...
查找问题在计算机科学中是一个经典的问题,包括线性查找、二分查找、哈希查找等多种方法。在实际应用中,查找问题具有广泛的研究和应用价值。 在这份资源中,您将学习到查找问题的定义和性质,以及如何使用Python...
[原网页] 程序员编程艺术第二十五章:Jon Bentley:90%无法正确实现二分查找 [原网页] 编程艺术第二十三~四章十一续:杨氏矩阵查找,倒排索引关键词Hash编码 [原网页] 六之再续:KMP算法之总结篇(12.09修订,必懂...
市面上能下载的《算法导论》中文版都没有目录(标签) 阅读极不方便 翻阅困难 本人 crocostone 亲自手动制作了完整的标签 包括章 节 小节的标签 在Acrobat 7 0和9 0版本和FoxitReader 4 2版本均能打开 而且 我精心...
Python版数据结构与算法-查找算法源代码,含顺序搜索、二分查找、哈希表搜索、树(图)数据查找源代码
算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法...
1.1.10 二分查找 28 1.1.11 展望 30 1.2 数据抽象 38 1.2.1 使用抽象数据类型 38 1.2.2 抽象数据类型举例 45 1.2.3 抽象数据类型的实现 52 1.2.4 更多抽象数据类型的实现 55 1.2.5 数据类型的设计 60 1.3 ...
1.1.10 二分查找 1.1.11 展望 1.2 数据抽象 1.2.1 使用抽象数据类型 1.2.2 抽象数据类型举例 1.2.3 抽象数据类型的实现 1.2.4 更多抽象数据类型的实现 1.2.5 数据类型的设计 1.3 背包、队列和栈 1.3.1 API...
20_二分查找 21_冒泡排序和选择排序 22_插入排序 23_希尔排序 24_归并排序 25_快速排序 26_Hash散列&ADT Map 27_树的嵌套列表实现 28_树结构的节点链接法实现 29_表达式解析树 30_树的遍历 31_python实现ADT ...
150个编程题问答从二叉树到二分查找,该部分涵盖了关于数据结构和算法的最常见、最有用的面试题以及最为精巧的解决方案。应对棘手算法题的5种行之有效的方法通过这5种方法,你可以学会如何处理并攻克算法难题,包括...
150个编程题问答从二叉树到二分查找,该部分涵盖了关于数据结构和算法的最常见、最有用的面试题以及最为精巧的解决方案。应对棘手算法题的5种行之有效的方法通过这5种方法,你可以学会如何处理并攻克算法难题,包括...
算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法...