【问题标题】:Binary search in Kernighan and Ritchie's C book [closed]Kernighan 和 Ritchie 的 C 书中的二进制搜索 [关闭]
【发布时间】:2021-12-02 01:20:25
【问题描述】:

Kernighan 和 Ritchie 为我们提供了一个对数组进行二进制研究的函数。它们的作用如下:

#include <stdio.h>


/* binsearch: find x in v[0] <= v[1] <= ... <= v[n-1] */
 int binsearch(int x, int v[], int n){
   int low, high, mid;
   low = 0;
   high = n - 1;
   while (low <= high) {
     mid = (low+high)/2;
     if (x < v[mid])
       high = mid + 1;
     else if (x > v[mid])
       low = mid + 1;
     else /* found match */
       return mid;
   }
   return -1; /* no match */
 }


int main() {
  int a[3]={3,4,7};
  int z = binsearch(3,a,3);
  printf("%d\n", z);
}

但是一旦我执行代码,就没有任何结果,编译也不会结束。我选择用于尝试代码的数组有什么问题吗?

【问题讨论】:

  • 尝试使用调试器单步执行。在进入循环时,我们有low = 0mid = 1high = 2。所以x &lt; v[mid] 是真的,我们也这样做high = mid + 1;。这设置了 high = 2,但 high 已经是 2,所以没有任何变化,下一次迭代做的事情完全相同。
  • @nate:你真的看过 K&R 吗?至少在我拥有的副本中,该行正确读取为high = mid - 1(第 58 页顶部)。
  • @rici 这么认为。感谢您的检查。
  • @SteveSummit 这个问题以及一些 cmets 和答案清楚地说明了为什么即使是有经验的程序员也应该使用已经调试过的库函数,而不是“我可以在几分钟内完成自己的工作”。
  • 众所周知,二分搜索算法于 1946 年首次被描述,但直到 1962 年才作为没有错误的实现发布。但 K&R(人民)知道这一点,并且 K&R( book) 于 1962 年之后出版,而 Kernighan 是 fanatical about testing,所以我无法想象 K&R 中的二进制搜索例程可能不正确。

标签: c kernighan-and-ritchie


【解决方案1】:

您可以进行一些跟踪,只需在不同的地方执行printf

首先,您可以在此行之后立即打印lowhighmid 的值:

mid = (low+high)/2;

你会发现这 3 个值永远不会改变,因为从 low=0 和 high=2 开始,mid 变为 1。x 小于 v[1],所以你将 high 设置为 mid+1,它仍然是 2 不变.

您现在可以纠正您的错误。

【讨论】:

  • 如果您要添加printf 语句,您还需要添加花括号,否则if...else 构造会搞砸
【解决方案2】:

绝对是 OP 错字。

// if (x < v[mid]) high = mid + 1;
if (x < v[mid]) high = mid - 1;  //  `+` --> `-`.

K&R 书看起来不错。

【讨论】:

  • 这是有道理的。再次查看 mid 值是没有意义的 - 如果它与我们正在寻找的匹配,则不需要再次迭代。
  • @Tim... 更不用说无限次数的迭代了。因为如果您不更改highlow &lt;= high 将继续为真。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多