【问题标题】:Binary search that returns the index where the value should be inserted二进制搜索,返回应该插入值的索引
【发布时间】:2021-02-20 23:35:53
【问题描述】:

我需要进行二进制搜索,除了普通函数之外,当找不到该值时,它会返回我必须插入新元素进行排序的索引。在下面的代码中,第二个 for 用于搜索要交换元素的索引。我需要做一个用二进制搜索替换它的函数。这种方法会是什么样子?

void insertion (int n, int v[])
{
   for (int j = 1; j < n; ++j) {
   int x = v[j];
   int i;
// this for searches where the value should be inserted
   for (i = j-1; i >= 0 && v[i] > x; --i) 
        v[i+1] = v[i];
        v[i+1] = x;
   }
}

我知道正常的二分查找是这样的。我需要改变什么?

    static int BinarySearchR (int [] array, int l, int r, int key) {
        int mid = ((r - l) / 2) + l;
        if (array[mid] == key) return mid;
        else if (array[mid] > key) return BinarySearchR(array, l, mid- 1, key);
        else if(array[mid] < key) return BinarySearchR(array, mid + 1, r, key); 
        return -1;
    }

【问题讨论】:

  • 你有什么问题?
  • 方法如何
  • 你必须使用递归二分搜索吗?
  • 递归或迭代

标签: java binary-search


【解决方案1】:

经过一些调整,它起作用了:

public static int BuscaBinariaI(int [] arr, int l, int r, int n) {
        int mid = 0;
            while(l < r){
                mid = l + (r - l)/2;
                if(arr[mid] == n) {
                    return -1;
                } 
                else if(arr[mid] > n){
                    r = mid - 1;
                    BuscaBinariaI( arr, l, r, n);
                }
                else {
                    l = mid + 1;
                    BuscaBinariaI( arr, l, r, n);
                }
            }
            if (mid>=arr.length) return arr.length;
            else if(arr[mid] > n) return mid ;
            else return mid + 1;
    }

【讨论】:

    【解决方案2】:

    Arrays.binarySearch 提供了这个:

    int foundPos = Arrays.binarySearch(array, key);
    if (foundPos < 0) {
        // Not found:
        int insertPos = ~foundPos;
    }
    

    肯定的结果给出找到的位置/索引。 否定结果给出插入位置的反码。

    另一个优点是这个函数对其他类型有很多重载, 以及子数组的其他变体。

    【讨论】:

    • 谢谢。在那种情况下,我不能使用 Arrays.binarySearch。但很高兴知道。
    • 是的,我认为这可能是家庭作业,但~foundPos(或-(foundPos+1))返回位置和找到/未找到的技巧应该已经看到了。仅返回一个位置的替代方案有一个巨大的缺点,即需要进行元素比较,并由索引检查保护,因为该位置可能在数组结束之后。
    • 为什么使用波浪号而不是负号?
    • @NomadMaker 波浪号是一个补码运算符,~0 = -1 和 ~(-1) = 0。~foundPos == -(foundPos+1)。该算法使用一个补码,将所有非负数转换为负数。但是 javadoc 也针对不习惯稀有位掩码波浪号运算符的普通程序员。我更喜欢使用它,因为它更短且更不容易出错:~i 与 -(i+1)。
    猜你喜欢
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 2020-04-02
    相关资源
    最近更新 更多