【问题标题】:Implementing Binary Search in C在 C 中实现二分查找
【发布时间】:2016-02-23 12:26:55
【问题描述】:

关于实现二分搜索的快速问题 :-)。这是我现在拥有的功能,我还没有完全弄清楚为 i 传递正确数字的逻辑。但是,当我调试这个函数时,我发现当value = values[i] (match)时,出现了意想不到的行为。

我的意图是返回 true,从而触发匹配并退出函数。实际行为结果返回 true; 然后返回false; (错误地)。有谁知道如何确保返回 true;退出函数?或指导我走向错误的提示?非常感谢!

bool search(int value, int values[], int n){

   int i = ((n - 1) / 2); 

   if(value == values[i])
   {
      return true;
   }
   else if(value < values[i])
   {
      n = i;
      search(value, values, n);
   }
   else if(value > values[i])
   {
      n = (i * 1.5);
      search(value, values, n);
   } 
   return false; 
}

【问题讨论】:

标签: c binary-search


【解决方案1】:

您缺少几个 return 关键字。

search(value, values, n);

应该是:

return search(value, values, n);

有两条这样的行。

如果没有那些return 关键字,函数总是会走到最后并返回false

更新,以回应 OP 的评论

您的函数没有任何检查来确保values 不会被越界访问。我认为它永远不会尝试访问具有负索引的任何内容,但它有机会访问索引高于允许的索引值的元素。我建议更改要使用的功能:

int search(int value, int values[], int start, int end)
{
   if ( start >= end )
   {
      return 0;
   }

   int mid = (start + end)/2; 

   if(value < values[mid])
   {
      return search(value, values, start, mid);
   }
   else if(value > values[mid])
   {
      return search(value, values, mid+1, end);
   } 
   else
   {
      return (value == values[mid]);
   }
}

并在从函数外部调用时使用正确的 startend 值调用它。

int values[] = {1, 4, 6, 8};
bool found = search(2, values, 0, sizeof(values));

【讨论】:

  • 谢谢@r-sahu!这修复了调试中的函数并返回了正确的发现。当我在我们更大的分配程序中测试它时,它导致了分段错误。我的实施中是否存在任何可能导致此问题的关键问题?
  • 最有可能的是,如果您在更大的应用程序中使用答案,它仍然会使用 bool search(int value, int values[], int n) 而不是调用搜索的 bool search(int value, int values[], int start, int end) 调用函数。
【解决方案2】:

让我评论一下,可以用你的界面编写一个有效的函数版本。比如:

bool search(int value, int values[], int n)
{
  if (n == 0) // searching in an empty set?
    return false;

  int i = (n - 1) / 2;

  if (value == values[i]) // the middle contains value?
    return true;
  else if (value < values[i]) // would be value to the left of i
    return search(value, values, i);
   else // so it would be to the right; no need of if (value > values[i])
     return search(value, values + i + 1, n - i - 1);
}

此函数与您的签名相同,通过元素数量n 和数组指针的基数来缩小搜索范围。向中心左侧搜索时,元素数减少到i,向右搜索时数组基址增加i + 1,元素数减少i + 1 .

请注意,您的第三个if 不是必需的;如果达到,则谓词始终为真,因为value 不等于不小于value[i],所以它更大。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-28
    • 2015-06-10
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2014-05-10
    相关资源
    最近更新 更多