设为首页 加入收藏

TOP

2.4.2 折半查找(2)
2014-03-11 13:03:59 来源: 作者: 【 】 浏览:107
Tags:2.4.2 查找

2.4.2  折半查找(2)

4. binarySearch如何给出查找结果?如果binarySearch成功地从数组中找到target,那么将返回target对应的数组元素的索引。索引一定不是负值,因此如果没有在数组中找到target,那么binarySearch会返回负值。

下面的C++函数binarySearch实现了上述思想。为了在后面对该函数进行箱式跟踪,将对binarySearch的两个递归调用分别标记为X和Y。
 

  1. /**     Searches the array anArray[first] through anArray[last]  
  2. for a given value by using a binary search.  
  3. @pre        0  <= first, last <= SIZE - 1, where SIZE is the  
  4. maximum size of the array, and anArray[first] <=  
  5. anArray[first + 1] <= ... <= anArray[last].  
  6. @post       anArray is unchanged and either anArray[index] contains  
  7. the given value or index == -1.  
  8. @param anArray      The array to search.  
  9. @param first        The low index to start searching from.  
  10. @param last     The high index to stop searching at.  
  11. @param target       The search key.  
  12. @return     Either index, such that anArray[index] == target, or -1.  
  13. */  
  14. int binarySearch(const int anArray[], int first, int last, int target)  
  15. {  
  16. int index;  
  17. if (first > last)  
  18. index = -1; // target not in original array  
  19. else  
  20. {  
  21. // If target is in anArray,  
  22. // anArray[first] <= target <= anArray[last]  
  23. int mid = first + (last - first) / 2;  
  24. if (target == anArray[mid])  
  25. index = mid; // target found at anArray[mid]  
  26. else if (target < anArray[mid])  
  27. // Point X  
  28. index = binarySearch(anArray, first, mid - 1, target);  
  29. else  
  30. // Point Y  
  31. index = binarySearch(anArray, mid + 1, last, target);  
  32. }       // end if  
  33. return index;  
  34. }    // end binarySearch 

注意,如果数组中包含了target,那么必然存在于first和last界定的数组段中。也就是说,下面的内容是成立的:
 

  1. anArray[first]    target    anArray[last] 

图2-10显示了binarySearch查找的箱式跟踪,在此这个函数查找包含1、5、9、12、15、21、29和31的数组。注意在图中用X和Y标记了binarySearch的两次递归调用。本章结尾的练习题16要求完成这个函数的其他箱式跟踪。

提示:当开发递归解决方案的时候,必须确保较小问题的解决方案确实可以提供原始问题的解决方案。例如,当每个较小的数组都已经被排序,并且被查找的值在第一个值和最后一个值之间时,binarySearch才起作用。

此外还需要考虑一个C++特有的实现问题。数组不会按值传送给函数,因此不存在数组的副本。C++的这种特征对诸如binarySearch这样的递归函数特别有用。如果数组anArray很大,就有可能需要多次递归调用binarySearch。如果每次调用都复制anArray,将造成内存和时间的大量浪费。此外由于不复制anArray,因此函数可以修改数组中的元素,除非像binarySearch那样把anArray指定为const。

注释:由于数组参数总是按引用传递,因此如果没有将数组指定为const,则函数可以修改数组

对于包含数组参数的递归函数的箱式跟踪,需要考虑另一个因素。因为数组anArray既不是值参数也不是局部变量,所以它并不是函数局部环境的一部分,各个箱内不应包含数组anArray的全部内容。因此,anArray在箱外表示,如图2-11所示,对anArray的所有引用都会影响这个表示。

注释:在箱式跟踪时,将引用参数放在箱外表示

提示:注意计算中点mid的C++语句为:
 

  1. int mid = first + (last - first)/2; 

而不是伪代码中建议的:
 

  1. int mid = (first + last)/2; 

如果打算查找一个元素数量为230(大约10亿)的数组,first与last的和可能超过最大的int值230-1。因此,计算first+last时将溢出从而得到一个负整数,进而使得mid成为负值。如果将这个值为负的mid用作数组的索引,将导致数组越界并得到不正确的结果。表达式first+(last-first)/2在代数上等同于(first+last)/2,但是避免了这个问题。
 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇2.4.2 折半查找(1) 下一篇2.4.3 查找数组中的最大值

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·HTTPS 详解一:附带 (2025-12-26 02:20:37)
·TCP/IP协议到底在讲 (2025-12-26 02:20:34)
·TCP和UDP在socket编 (2025-12-26 02:20:32)
·有没有适合新手练习 (2025-12-26 01:48:47)
·用清华镜像网怎么下 (2025-12-26 01:48:44)