算法学习--排序与查找答辩.docxVIP

  1. 1、本文档共27页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 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

文档评论(0)

1112111 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档