C ++中的二进制搜索函数返回无限循环

时间:2016-01-26 20:31:00

标签: c++ for-loop while-loop binary-search

好吧,这是一个更多的查询,所以我可以理解这是做什么,但是,我有以下代码。同样,while循环将返回一个无限循环,我将while更改为基本for(int i=0;i<n;i++)循环,它正常工作和输出。

发生了什么事?我实际上不知道为什么我的while循环会被卡住而for循环没有。

bool binary_search(const string A[], int n, string name, int &count){
   count = 0;                  // Count initialization
   int fst = 0;
   int lst = n+1;              // First, Last and Middle array elements
   int mid = 0;

   while(fst<=lst)
   {
      count++;

      mid = (fst+lst)/2;      // Calculate mid point of array
      if (A[mid]==name)       // If value is found at mid
      {
         return true;
      }
      else if (A[mid]>name)
      {                       // if value is in lower
         lst = mid++;
         //cout << "elseIfME!" << endl;
      }
      else if (A[mid]<name)
      {                       // if value is in higher
         fst = mid--;
         //cout << "elseME!" << endl;
      }
   }
   return false;

}

2 个答案:

答案 0 :(得分:6)

您的条件应如下所示::

// Assuming that the array you are searching is sorted in descending order
// and hence the else-if conditions
else if (A[mid]>name)
{                       
   lst = mid + 1;
}
else if (A[mid]<name)
{      
   fst = mid - 1;
}

你使用的后增量是没用的!因为,当您发布增量(mid++mid--)时,它返回原始值(mid),然后值递增/递减,所以实际上,您设置{{1每次找不到元素时,代码中都会出现fst = mid

因此,当lst = mid在二进制搜索期间您将数组中的搜索域缩短为仅1个元素时,您会计算fst = lst等于mid并且fst,如果找不到该元素,您可以指定lstfst = mid,因为这是您的循环应停止的位置,并停止条件lst = mid应该被违反,这不是,因此是无限循环。

即使在通过比较中心元素缩小搜索范围的搜索过程中,您也必须排除刚刚比较的中心元素,而不是因为后期增量而没有!

如果您希望它起作用,您也可以使用预增量和预减量! (fst <= lst++mid

答案 1 :(得分:2)

我认为你的逻辑是倒退的。 if (A[mid]>name)是正确的,然后名称位于列表的下半部分,但是您在此之后的中间位置增加到列表的一部分,它无法进入。在这种情况下,您应该设置lst = mid-1,而不是mid--,因为它将lst设置为mid,然后递减它。对于测试if (A[mid]<name),您应该设置fst = mid + 1,例如:

  else if (A[mid]>name)
  {                       // if value is in lower
     lst = mid - 1;
     //cout << "elseIfME!" << endl;
  }
  else if (A[mid]<name)
  {                       // if value is in higher
     fst = mid + 1;
     //cout << "elseME!" << endl;
  }

基本上,原始逻辑在确定值应该在列表中的部分时,会增加此部分的大小,而不是缩短它,因此您只需继续搜索较大的子列表,而不是较小的子列表。