Handwriting together! Binary search!

Binary search, also called half search. Using the idea of ​​dichotomy, the data is divided into two halves each time it is searched, starting from the middle value.

 

 

As shown in the figure above, low and high represent the subscripts on both sides of the array, and mid represents the middle subscript of the array.

  • If the target value is greater than the middle value, that is, the target value is between mid and high, the value of low is modified . Then compare the median value.

  • If the target value is smaller than the middle value, that is, the target value is between low and mid, the value of high is modified . Then compare the median value.

The above is the process of binary search, how to find its time complexity ❓

Assuming that the length of the array is n, the length becomes n / 2 after searching once, and then becomes n / 4 after searching again, and so on. In the worst case, n / 2 ^ k is empty, and the search stops. So we have the following formula:

n * n / 2 * n / 4 * n / 8 * n / 2 ^ k ·····

The above is a sequence of proportional numbers. When n / 2 ^ k = 1, k is the number of searches. That is, k = log2n, so the time complexity is O (logn), which is a very efficient algorithm. 

Non-recursive version

function binary_search(arr, key) {
    var low = 0, high = arr.length - 1;
    while(low <= high){
        var mid = parseInt(low + (high - low) / 2); 
        if(key === arr[mid]){
            return  mid;
        } else if (key > arr[mid]){
            low = mid + 1;
        } else if (key < arr[mid]){
            high = mid -1;
        } else {
            return -1;
        }
    }
};
var arr = [5,13,19,21,37,56,64,75,80,88,92 ];
var result = binary_search (arr, 21 );
console.log(result);
It should be noted that the value of mid should not be written as (low + high) / 2, because if low + high is large, it will overflow. So writing low + (high-low) / 2 will not have this problem.
Further, of course, you can also use bit operation to replace low + ((high-low) >> 1) with low + (high-low) / 2, and this bit operation is more efficient.

Recursive version

In addition to the loop method described above, binary search can also be implemented using recursion.

function binary_search(arr,low, high, key) {
    if (low > high){
        return -1;
    }
    var mid = low + ((high - low) >> 1);
    if(arr[mid] == key){
        return mid;
    }else if (arr[mid] > key){
        high = mid - 1;
        return binary_search(arr, low, high, key);
    }else if (arr[mid] < key){
        low = mid + 1;
        return binary_search(arr, low, high, key);
    }
};
var arr = [5,13,19,21,37,56,64,75,80,88,92 ];
var result = binary_search (arr, 0, 11, 21 );
console.log(result);

3. There is duplicate data in the array, how to find out where the element last appeared

The same idea as the binary search introduced above:

function binary_search(arr, key) {
    var low = 0, high = arr.length - 1;
      while (low <= high) {
        var mid =  low + ((high - low) >> 1);
        if (arr[mid] > key) {
          high = mid - 1;
        } else if (arr[mid] < key) {
          low = mid + 1;
        } else {
          if ((mid == arr.length - 1) || (arr[mid + 1] != key)) return mid;
          else low = mid + 1;
        }
    }
    return -1;
}
var arr = [5,13,19,21,21,37,56,64,75,80,88,92 ];
var result = binary_search (arr, 21 );
console.log(result);

 

 

Guess you like

Origin www.cnblogs.com/magicg/p/12749445.html