强大的二分查找法(Binary Search)

今天帮助David 调程序。他在做Windows下程序分析,使用一个数组存放目标程序heap中所有的数据结构(地址和Size),然后扫描该程序全局数据段所有内容,如果某个指针指向的值落在heap中某个数据结构地址范围内,就建立从全局数据段到该数据结构的路径。

David给我演示时, 说运行Toy program 没问题,但运行一个比较大的真实程序时,就会出现性能问题,果然,我们等了二十多分钟,还是没有算完。于是我检查了他的代码,告诉他问题可能出在检查指针是否指向有效数据结构时,他是用的线性查找方法。我说,考虑到他的数组已经排序, 使用二分查找法,会快很多,因为算法复杂度从O(N)降到了O(logN)。没多久,他就写好了新的程序, 他很兴奋地告诉我:同样的大程序,不到一分钟就算好了,而之前的程序需要1个小时才能算完,我再次检查他的程序,发现目标程序比较大时,heap中的数据结构有几千个, 难怪二分查找的性能好如此之多。

我于是想到经典书籍《编程珠玑(Programming Pearls)》, 该书花了大量篇幅来讲二分查找,2, 4, 9, 11, 13章都有直接讲到二分查找,可见二分查找的重要性。第二章有段话精确地描述了我今天碰到的例子:“程序员一开始可使用简单的顺序查找数据结构。顺序查找通常也够快了。如果程序变得太慢了,那么对表进行排序然后使用二分查找往往可以排除这个瓶颈。”

第二章提出了三个典型二分查找问题,问题A如下:“给定一个包含32位整数的顺序文件,它至多只能包含40亿个这样的整数,并且整数的次序是随机的。请查找一个此文件中不存在的32位整数。在有足够主存的情况下,你会如何解决这个问题?如果你可以使用若干外部临时文件但可以用主存却只有上百字节, 你会如何解决这个问题?”

如果我们有足够内存,当然很简单,不需要使用二分查找法。但如果只有上百字节内存, 线性查找就无法使用了。我们使用二分查找,设定2^32 / 2 为中点M(假设都为正整数,无负数),然后遍历文件中所有整数,把大于M的放一个临时文件,小于M的放另一个临时文件,并计算每个文件中整数个数,如果小于2^32 / 2 个,那么该文件的整数中至少有一个漏洞,重复以上过程就能找到一个文件中不存在的32位整数了。二分查找法让这个问题突然变得简单了好多。就如书中所说“看起来很困难的问题解决起来可能很简单,并且还很可能出人意料... ... 只有经过广泛的研究之后才能对算法具备那种出神入化的理解力。 ”

感谢David的程序和《编程珠玑》, 让我对二分查找有了更为深入的理解。

转载于:https://www.cnblogs.com/guyufei/archive/2013/05/24/3096902.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值