来自排序数组的X的floor和ceil

时间:2013-09-13 01:26:53

标签: java arrays algorithm binary-search

从已经排序的数组中查找数字X的地板和ceil。 e.g。

  

a [] = {3,7,9,10,15}

     
      
  • 如果X = 2,floor = N / A,ceil = 3
  •   
  • 如果X = 3,floor = 3,ceil = 3
  •   
  • 如果X = 4,floor = 3,ceil = 7
  •   
  • 如果X = 16,floor = 15,ceil = N / A
  •   

我认为我们大多数人都知道解决方案,即我们可以通过修改二进制搜索找到floor / ceil。但是修改二进制搜索的问题是我们需要处理很多边界条件。但我发现相同的二元搜索算法确实有效,但对于地板我们只需要写if low > high return low和ceil if low > high return high 。如果floor返回-1则显示N / A,如果ceil返回的值大于数组索引而不是显示N / A.

  

algo for floor:

int floorSearch(int a[], int low, int high, int x)
{
    if(low > high){
        return low;
    }
    int mid = (low+high)/2;
    if(a[mid]>x){
        return floorSearch(a, low, mid-1, x);
    }
    else if(a[mid]<x){
        return floorSearch(a, mid+1, high, x);
    }
    else{
        return mid;
    }
}
  

和ceil:

int ceilSearch(int a[], int low, int high, int x)
{
    if(low > high){
        return high;
    }
    int mid = (low+high)/2;
    if(a[mid]>x){
        return ceilSearch(a, low, mid-1, x);
    }
    else if(a[mid]<x){
        return ceilSearch(a, mid+1, high, x);
    }
    else{
        return mid;
    }
}

这很简单,不是吗?我检查了很多输入,它确实有效,但我未能证明算法的正确性。有人可以尝试证明正确性,或者您也可以提供此算法失败的样本输入。感谢。

4 个答案:

答案 0 :(得分:1)

关于如何进行证明的提示:

  1. 这些算法的正确性证明将遵循算法的递归结构;即使用结构感应证明(查阅)。

  2. 查看标准二进制搜索的证明并弄清楚它是如何构建的。

  3. 如果您的代码中存在错误,那么您应该无法找到正确的证明;见其他评论和其他答案!

答案 1 :(得分:1)

代码中存在传统错误。它使用int mid = (low+high)/2;。如果数组非常大,则可能会使加法溢出为负结果,使得中间为负数。

可以使用int mid = (low+high)>>>1;修复错误,就像在java.util.Arrays binarySearch方法中所做的那样。 >>> 1实际上是无符号除以2。

答案 2 :(得分:0)

由于您只修改了条件if(low > high),请注意在普通二进制搜索中等效的内容。理解二进制搜索的证明,在这里确定正确性应该是微不足道的。

答案 3 :(得分:0)

这是一个测试案例,它会破坏你的ceilSearch代码。

a = {3,7,9,11,13},x = 10.

我在每个递归调用中列出低,高和中:

(0,4,2) - &gt; a [2] = 9&lt; X

(3,4,3) - &gt; a [3] = 11&gt; X

(3,2,2) - &gt;低&gt;高,返回低= 2。

正确答案是3,而不是2。