虽然Loop永远运行,但不会返回二进制搜索

时间:2018-04-09 19:47:20

标签: c binary-search

尝试为反向数组输入实现二进制算法。 当我执行测试用例时 - 5 4 3 2 1它显示了一个空白屏幕,即while循环无限运行。现在一直调试它,但无法弄清楚我哪里出错了。

#include <stdio.h>
#include <stdlib.h>

int findright(int arr[], int key, int low, int high);

void main() {
  int n, i, arr[200], key;
  scanf("%d %d\n", &n, &key);
  for (int i = 0; i < n; i++) {
    scanf("%d", &arr[i]);
  }
  int a = findright(arr, key, 1, n - 1);
  printf("%d", a);
}

int findright(int arr[], int key, int low, int high) {

  int mid = (low + high) / 2;
  while (low <= high) {
    if (arr[mid] == key) {
      return mid;
    } else if (arr[mid] > key) {
      findright(arr, key, mid + 1, high);
    } else {
      findright(arr, key, low, mid - 1);
    }
  }
  return -1;
}

2 个答案:

答案 0 :(得分:5)

在您的循环while (low <= high) { ...中,lowhigh的值不会改变;因此,如果循环一旦输入,它将永远不会返回。

当你使用递归时,你不需要循环:

int findright(int arr[], int key, int low, int high) {

  if (low > high) { // anchor stopping recursion
    return -1;  // indicate that key was not found...
  }

  int mid = (low + high) / 2;
  if (arr[mid] == key) {
      return mid;
  } else if (arr[mid] > key) {
      return findright(arr, key, mid + 1, high);
  } else {
      return findright(arr, key, low, mid - 1);
  }
}

Demo.

进一步注意 - 正如MFisherKDX所提到的那样 - &#34;你的主人也有一个一个一个错误。你传递1为低,因此永远不会检查第0个元素&#34;。

答案 1 :(得分:1)

我看到的问题:

  1. while需要更改为if
  2. 递归调用需要在它们之前有return
  3. 您正在使用low
  4. 的错误值调用该函数
    int findright(int arr[], int key, int low, int high) 
    {
        int mid = (low + high) / 2;
        if (arr[mid] == key)
        {
            return mid;
        }
    
        // Terminate recursion when the item is not found.
        if ( low == high )
        {
            return -1;
        }
    
        if (arr[mid] > key)
        {
            return findright(arr, key, mid + 1, high);
        }
    
        else
        {
            return findright(arr, key, low, mid - 1);
        }
    }
    

    电话

    int a = findright(arr, key, 1, n - 1);
    

    需要更改为:

    int a = findright(arr, key, 0, n - 1);
    

    需要注意的一点是,标准库函数与迭代器一起使用,以使 end 超过最后一个有效迭代器。使用索引实现函数时,类似值将是大于最高有效索引的1的索引。您可以将该函数称为:

    int a = findright(arr, key, 0, n);
    

    并以稍微不同的方式实现该功能:

    int findright(int arr[], int key, int low, int high) 
    {
        // Terminate recursion when the item is not found.
        if ( low == high )
        {
            return -1;
        }
    
        int mid = (low + high) / 2;
        if (arr[mid] == key)
        {
            return mid;
        }
    
        if (arr[mid] > key)
        {
            return findright(arr, key, mid + 1, high);
        }
    
        else
        {
            return findright(arr, key, low, mid);
        }
    }