- 1、本文档共27页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
算法学习--排序与查找
作者: HYPERLINK /qinzhaokun \t _blank qinzhaokun
二分查找
我们都知道二分查找算法,实际上二分查找以及其扩展应用是很广泛的。这里收集了一些和二分查找有关的有趣问题。强烈建议大家看完问题后最小化浏览器,先尝试自己去解决,然后再看代码,问题都不是太难。
问题1描述
给一个已经排序的数组,其中有N个互不相同的元素。要求使用最小的比较次数找出其中的一个元素。(你认为二分查找在排序数组里找一个元素是最优的算法的吗?)
不需要太多的理论,这是一个典型的二分查找算法。先看下面的代码:
int BinarySearch(int A[], int l, int r, int key)
{
int m;
while( l = r )
{
m = l + (r-l)/2;
if( A[m] == key ) //第一次比较
return m;
if( A[m] key ) // 第二次比较
l = m + 1;
else
r = m - 1;
}
return -1;
}
理论上,我们最多需要 logN+1 次比较。仔细观察,我们在每次迭代中使用两次比较,除了最后比较成功的一次。实际应用上,比较也是代价高昂的操作,往往不是简单的数据类型的比较。减少比较的次数也是优化的方向之一。
下面是一个比较次数更少的实现:
// 循环不变式: A[l] = key A[r] key
// 边界: |r - l| = 1
// 输入: A[l .... r-1]
int BinarySearch(int A[], int l, int r, int key)
{
int m;
while( r - l 1 )
{
m = l + (r-l)/2;
if( A[m] = key )
l = m;
else
r = m;
}
if( A[l] == key )
return l;
else
return -1
在while循环中,我们仅依赖于一次比较。搜索空间( l-r )不断缩小,我们需要一个比较跟踪搜索状态。
需要注意的,要保证我们恒等式(A[l] = key A[r] key)正确,后面还会用到循环不变式。
问题2描述
给一个有N个互不相同的元素的已排序数组,返回小于或等于给定key的最大元素。 例如输入为 A = {-1, 2, 3, 5, 6, 8, 9, 10} ? key = 7,应该返回6.
分析:
我们可以用上面的优化方案,还是保持一个恒等式,然后移动 左右两个指针。最终 left指针会指向 小于或等于给定key的最大元素(根据恒等式A[l] = key and A[r] key)。
- 如果数组中所有元素都小于key,左边的指针left 会一直移动到最后一个元素。
- 如果数组中所有元素都大于key,这是一个错误条件,无答案。
- 如果数组中的所有元素都 = key,这是最坏的情况根据下面的实现
int Floor(int A[], int l, int r, int key)
{
int m;
while( r - l 1 )
{
m = l + (r - l)/2;
if( A[m] = key )
l = m;
else
r = m;
}
return A[l];
}
// 初始调用
int Floor(int A[], int size, int key)
{
// 如果 key A[0] 不符合条件
if( key A[0] )
return -1;
return Floor(A, 0, size, key);
}
问题3描述
给一个有重复元素的已排序数组,找出给定的元素key出现的次数,时间复杂度要求为logN.
分析
其实可以对上面的程序稍作修改,思路就是分别找出key 第一次出现的位置和最后一次出现的位置。
// 输入: 数组区间 [l ... r)
// 循环不变式: A[l] = key and A[r] key
int GetRightPosition(int A[], int l, int r
您可能关注的文档
最近下载
- 一种钢铁综合废水浓盐水的减量化、资源化处理组合方法与系统.pdf VIP
- 《碳中和管理体系 要求》(征求意见稿).pdf
- 医院银行存款管理制度.docx VIP
- 新北师大版数学五年级上册第六单元“组合图形面积”单元试卷 .pdf VIP
- 人教版高中英语必修一全册教学课件.pptx
- 《工逆向工程与增材制造》课件——17. Geomagic Design X 草图建模方法 .pptx VIP
- 海姆立克急救法-(精).ppt VIP
- 北师大版九年级下册数学全册同步练习.docx VIP
- 2025全国青少年模拟飞行考核理论知识题库40题及参考答案1套.docx VIP
- 在线网课学习课堂《兵棋(中国人民武装警察部队警官学院)》单元测试考核答案.docx VIP
文档评论(0)