通过二进制搜索递归插入

时间:2014-11-15 20:58:22

标签: java sorting insert

我有一个排序数组,想要递归地找到插入元素的位置。例如。插入值为3的数组2,4,5,6,7,8,12,35,算法应该返回3必须插入的位置的索引(索引1)。 以下代码有时会起作用,有时会陷入无限循环。最终我的大脑感觉像果冻,我请求你的帮助。这是代码:

private static int insertRec(int[] a, int e, int l, int r) {
    int mid = l + r / 2;
    if (l == r || a[mid] == e) return mid;
    if (e > a[mid]) insertRec(a, e, mid + 1, r);
    if (e < a[mid]) insertRec(a, e, l, mid - 1);
    return -1;

}

使用假设的工作代码进行编辑:

private static int insertRec(int[] a, int e, int l, int r) {
    int mid = (l + r) / 2;
    if (l == r || a[mid] == e) return mid;
    else if (e > a[mid]) return insertRec(a, e, mid + 1, r);
    else if (e < a[mid]) return insertRec(a, e, l, mid - 1);
    return -1;

}

1 个答案:

答案 0 :(得分:3)

int mid = l + r / 2;

应该是

int mid = (l + r) / 2;

编辑:此外,您可以查看STL算法lower_bound的说明,正如我所理解的那样,它正是您想要的。基于此的实现如下:

int lb(int a[], int last, int val) { // array, len of the array, element to insert
  int it, count, step;
  int first = 0;
  count = (last-first);
  while (count > 0) {
    it = first;
    step = count/2;
    it += step;
    if (a[it] < val) {
      first = ++it;
      count -= step+1;
    } else
      count = step;
  }
  return first;
}

EDIT2 :您的代码有一些错误可以正常工作,其中包括:

  • 在第二行中,您无法检查a[mid] == e是否因为您要插入的元素可能不存在于数组中。这会导致在几种情况下返回-1。

  • 无限循环来自于计算mid并稍后分配mid+1mid-1的方式。

  • 因为您要插入的元素可能等于数组中的某些元素,因此您将错误地返回,因为您要比较e > a[mid]e < a[mid]

我建议你看看这个关于二进制搜索的奇妙post。无论如何,这里的算法试图遵循更多可能的风格并使用帖子的信息。希望它有所帮助。

private static int insertRec(int[] a, int e, int l, int r) {
    int mid = l + (r - l) / 2;
    if (l == r) return l;
    else if (a[mid] < e) return insertRec(a, e, mid+1, r);
    else return insertRec(a, e, l, mid);
}