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

Binary Search Function in C++ returns infinite loop

本文关键字:函数 返回 无限循环 搜索 二进制 C++      更新时间:2023-10-16

好吧,这更像是一个查询,所以我可以理解这是在做什么,但是,我有下面的代码。照原样,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;
}

你的条件应该是这样的::

// 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),然后值递增/递减,所以实际上,每次找不到元素时,你都会在代码中设置fst = midlst = mid

因此,发生的情况是,当您fst = lst在二叉搜索期间将数组中的搜索域缩短为仅 1 个元素时,您计算mid等于 fstlst ,如果找不到该元素,您要么分配fst = mid要么lst = mid,因为这是您的循环应该停止的地方, 而停止条件fst <= lst应被违反,这不是,因此是无限循环。

即使在搜索过程中,当您通过比较中心元素来缩小搜索范围时,您也必须排除刚刚比较的中心元素,而您不会因为帖子增量而排除!

如果您希望它工作,您也可以使用预递增和预递减!( ++mid--mid

我认为你的逻辑是倒退的。 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;
  }

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