网站大量收购闲置独家精品文档,联系QQ:2885784924

算法学习--排序与查找要点分析.docx

  1. 1、本文档共27页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
算法学习--排序与查找作者: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] keyint GetRightPosition(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;

文档评论(0)

希望之星 + 关注
实名认证
内容提供者

我是一名原创力文库的爱好者!从事自由职业!

1亿VIP精品文档

相关文档