二进制搜索未知大小的数组

时间:2013-05-13 00:33:38

标签: algorithm search binary-search

假设已经给出了一个数组并且想要在该数组中找到元素,那么如何使用二进制搜索搜索该数组中的元素,并且给定的数组已经排序并且数组的大小未知。 可以应用线性搜索,但我试图找出比线性算法更快的搜索。

7 个答案:

答案 0 :(得分:8)

如果你可以测试你是否已经超出数组范围,那么你可以使用修改后的二进制搜索(假设基于1的数组):

  1. lower = 1,upper = 1;
  2. while(A [upper]< element)upper * = 2;
  3. 正常二进制搜索(下,上)。
  4. 否则,没有真正的方法可以做到:假设你找到的东西与你需要的元素相等,你不知道它是否已经脱离了数组。

答案 1 :(得分:2)

假设数组A已排序(否则您无法进行二分查找),并且您要搜索的元素为k,则可以找到索引i,使得k <1。 A [i],然后从1到i进行二进制搜索(1索引数组)。这是因为一旦k <1。保证在排序元素A [1..i]的范围内找到(或找不到)a [i],k。

要找到索引i,您将从i = 1开始,然后在k> 1时加倍。 A [i]中。这就像二进制搜索,除了你的搜索范围加倍,因此它仍然有一个O(log n)运行时间。

该算法类似于:设置i = 1,然后重复直到k <= A [i]:

  • 如果k> A [i]然后让i = i * 2

如果k == A [i],那么你就完成了,否则就像往常一样在A [1..i]上进行二分搜索。

答案 2 :(得分:1)

以下内容应该有效(尚未测试),但应与二分查找具有相同的界限O(log(n))

private bool hasValue(int[] array, int search, int start, int end)
{
    int mid = (start+end)/2;

    try
    {
        //Check to see if we can grab the value
        int value = array[mid];

        //If we are here, we are in the array

        //Perform the binary search
        if (value==search)
            return true;
        else if (end <= start)
            return false;
        else if (value>search)
            return hasValue(array, search, start, mid);
        else
            return hasValue(array, search, mid, end*2);

    }
    catch(ArrayIndexOutOfBoundsException e)
    {
        //If we are here, then we were outside the array, so 
        //loop through the lower half
        return hasValue(array, search, start, mid);
    }


}

public bool hasValue(int[] array, int search)
{
    // 0 is the start of the array (known)
    // 1 is the end--start with any number that is greater than max(start, 1)
    return hasValue(array, search, 0, 1);
}

以下是一个示例用法

// 2 is the value you are looking for
bool hasTwo = hasValue(array, 2);

答案 3 :(得分:0)

这是一个开始:

我可能会尝试这样的东西(用Java-esqe语言编写)。 (假设整数数组)

int endOfArray = 10;
try {
   while (true) {
     int value = theArray[endOfArray*2];
     if (value > requestedValue)  // good enough 
        return doBinarySearch(theArray, 0, endOfArray, requestedValue);
     else
       endOfArray*=2;
   }
}

catch (ArrayIndexOutOfBoundsException aioob) {
  // we know that the end of the array is less than endOfArray*2 but > endOfArray
  // do something clever here TBD.   :-)
}

注意稍后添加:如果数组是“C-like”并且最后有0,那么您还必须检查它。顺便说一句,如果有人对“聪明的东西”部分有一个简单的解决方案,请随时编辑答案。

答案 4 :(得分:0)

这个对我有用,这是O(log N + log N),即O(log N)? 这个也以有效的方式适合子阵列。 O(log N)

static int bSearch (int needle, int[] arr)
    {
    boolean done = false;
    int i = 1;
    int lower = 0;
    int upper = 1;
    int temp;
    while (!done)
    {
        try{
            if (needle == arr[upper]) 
                return upper;
            else if (needle > arr[upper])
            {
                temp = lower;
                lower = upper;
                upper = temp + (int) Math.pow(2,i);
                i = i + 1;
            }
            else
            {
                done = true;
                break; //found the upper bounds
            }
        }
        catch (IndexOutOfBoundsException e)
        {
        upper = (upper -lower) / 2;
            i = 0;
        }
    }
    if (done == true)
        //do normal binary search with bounds lower and upper and length upper-lower
    else
        return -1;
    }

答案 5 :(得分:0)

var1 = 3
:: var2 = var1 + 2 

此解决方案适用于1索引数组。它对我有用。

答案 6 :(得分:0)

Python解决方案:如果数组中存在元素,则此方法将起作用

def searchArray(nums, element):
    if nums[0] == element: return 0
    i = 1
    base = 0
    done = False
    while not done:
        try:
            if nums[base + i] == element:
                print('if')
                return base + i
            elif nums[i] < element:
                print('elif')
                i = i * 2
            else:
                print('else')
                done = True
                print('base, i', base, i)
                base = base + i//2
                i = 1
        except:
            print('out of bound base, i', base, i)
            base = base + i//2
            i = 1
            
nums = [2, 3, 5, 6, 8, 9, 10, 11]
print(searchArray(nums, 11))