Binary search of several different numbers in a large array with a minimum number of comparisons

I have a large array of size n (say n = 1,000,000) with values โ€‹โ€‹monotonically non-decreasing. I have a set of key values โ€‹โ€‹"k" (say k = {1,23,39,55, ..}). Suppose the key values โ€‹โ€‹are sorted. I have to find the index of these key values โ€‹โ€‹in a large array using the minimum number of comparisons. How to use binary search to search for several unique values? Doing this separately for each key value requires a large number of comparisons. Can I use the reuse of some of the knowledge that I learned in one search, ever, when I search for another element in the same large array?

+4
source share
6 answers
  • Sort the needles (the values โ€‹โ€‹you will be looking for).
  • Create an array of the same length as the needles, with each element being a pair of indices. Initialize each pair with {0, len(haystack)}. These pairs represent all knowledge of the possible locations of the needles.
  • Look at the average value in a haystack. Now do a binary search for this value in your needles. For all smaller needles, set the upper bound (in the array from step 2) to the current haystack index. For all large needles, set the lower limit.
  • 3, , . , 3. , : ( , ).

- , , , , , .


, NumPy - . Python , , numpy.searchsorted(), API, this:

    /*
     * Updating only one of the indices based on the previous key
     * gives the search a big boost when keys are sorted, but slightly
     * slows down things for purely random ones.
     */
    if (@TYPE@_LT(last_key_val, key_val)) {
        max_idx = arr_len;
    }
    else {
        min_idx = 0;
        max_idx = (max_idx < arr_len) ? (max_idx + 1) : arr_len;
    }

, , , , , , . , , , , .


, , , , , , , , : , .. , , , , B ( / , ). len (haystack)/2, ( , ).
+5

- , , : , .

, N = 2 ^ n, K = 2 ^ k : (n ) N/2. 2 "" (n-1 ), N/4 ...

, n + 2 (n-1) + 4 (n-2) +... + 2 ^ (k-1) (n-k + 1). K.n-K.k = K. (n-k).

, ( K.n). , ( , ) .

UPDATE:

K N .

Knuth Vol. 3, 5.3.2, , ceiling(lg(C(N+K,K))) ( C(N+K,K) ). K N, lg((N^K/K!) K lg(N) - K lg(K) = K.(n-k).

, , .

+4
  • .
  • Go 2.

, .

+2

, C, Javascript, , . , ... , . 1 , 2,5 . , , . .

        singleSearch=function(array, num) {
            return this.singleSearch_(array, num, 0, array.length)
        }

        singleSearch_=function(array, num, left, right){
            while (left < right) {
                var middle =(left + right) >> 1;
                var midValue = array[middle];

                if (num > midValue) {
                    left = middle + 1;
                } else {
                    right = middle;
                }
            }
            return left;
        };


        multiSearch=function(array, nums) {
            var numsLength=nums.length;
            var results=new Int32Array(numsLength);
            this.multiSearch_(array, nums, 0, array.length, 0, numsLength, results);
            return results;
        };

        multiSearch_=function(array, nums, left, right, numsLeft, numsRight, results) {
            var middle = (left + right) >> 1;
            var midValue = array[middle];
            var numsMiddle = this.singleSearch_(nums, midValue, numsLeft, numsRight);
            if ((numsRight - numsLeft) > 1) {
                if (middle + 1 < right) {
                    var newLeft = middle;
                    var newRight = middle;
                    if ((numsRight - numsMiddle) > 0) {
                        this.multiSearch_(array, nums, newLeft, right, numsMiddle, numsRight, results);
                    }
                    if (numsMiddle - numsLeft > 0) {
                        this.multiSearch_(array, nums, left, newRight, numsLeft, numsMiddle, results);
                    }
                }
                else {
                    for (var i = numsLeft; i < numsRight; i++) {
                        var result = this.singleSearch_(array, nums[i], left, right);
                        results[i] = result;
                    }
                }
            }
            else {
                var result = this.singleSearch_(array, nums[numsLeft], left, right);
                results[numsLeft] = result;
            };
        }
0

// , . x // arr [l..r] , -1. โ€‹โ€‹

int binarySearch(int arr[], int l, int r, int x)
{
   if (r >= l)
   {
        int mid = l + (r - l)/2;

        // If the element is present at one of the middle 3 positions
        if (arr[mid] == x)  return mid;
        if (mid > l && arr[mid-1] == x) return (mid - 1);
        if (mid < r && arr[mid+1] == x) return (mid + 1);

        // If element is smaller than mid, then it can only be present
        // in left subarray
        if (arr[mid] > x) return binarySearch(arr, l, mid-2, x);

        // Else the element can only be present in right subarray
        return binarySearch(arr, mid+2, r, x);
   }

   // We reach here when element is not present in array
   return -1;
}
-1

All Articles