📜  元二进制搜索|单面二元搜索

📅  最后修改于: 2021-04-22 09:00:41             🧑  作者: Mango

元二进制搜索(Steven Skiena在“算法设计手册”第134页上也称为单面二进制搜索)是二进制搜索的一种改进形式,它可以增量地构造数组中目标值的索引。像普通的二进制搜索一样,元二进制搜索需要O(log n)的时间。

例子:

Input: [-10, -5, 4, 6, 8, 10, 11], key_to_search = 10
Output: 5

Input: [-2, 10, 100, 250, 32315], key_to_search = -2
Output: 0

确切的实现有所不同,但是基本算法有两个部分:

  1. 找出存储最大数组索引所需的位数。
  2. 通过确定索引中的每个位应设置为1还是0,来逐步构造数组中目标值的索引。

方法:

  1. 存储表示变量lg中最大数组索引的位数
  2. 使用lg在for循环中开始搜索
  3. 如果找到元素,则返回pos
  4. 否则,递增构造索引以达到for循环中的目标值
  5. 如果找到元素,则返回pos否则为-1

下面是上述方法的实现:

C++
// C++ implementation of above approach
  
#include 
#include 
#include 
using namespace std;
  
// Function to show the working of Meta binary search
int bsearch(vector A, int key_to_search)
{
    int n = (int)A.size();
    // Set number of bits to represent largest array index
    int lg = log2(n-1)+1; 
  
    //while ((1 << lg) < n - 1)
        //lg += 1;
  
    int pos = 0;
    for (int i = lg ; i >= 0; i--) {
        if (A[pos] == key_to_search)
            return pos;
  
        // Incrementally construct the
        // index of the target value
        int new_pos = pos | (1 << i);
  
        // find the element in one
        // direction and update position
        if ((new_pos < n) && (A[new_pos] <= key_to_search))
            pos = new_pos;
    }
  
    // if element found return pos otherwise -1
    return ((A[pos] == key_to_search) ? pos : -1);
}
  
// Driver code
int main(void)
{
  
    vector A = { -2, 10, 100, 250, 32315 };
    cout << bsearch(A, 10) << endl;
  
    return 0;
}
  
// This implementation was improved by Tanin


Java
//Java implementation of above approach 
import java.util.Vector;
import com.google.common.math.BigIntegerMath;
import java.math.*;
  
class GFG {
  
// Function to show the working of Meta binary search 
    static int bsearch(Vector A, int key_to_search) {
        int n = (int) A.size();
        // Set number of bits to represent largest array index
        int lg = BigIntegerMath.log2(BigInteger.valueOf(n-1),RoundingMode.UNNECESSARY) + 1;
   
        //while ((1 << lg) < n - 1) {
        //    lg += 1;
        //}
  
        int pos = 0;
        for (int i = lg - 1; i >= 0; i--) {
            if (A.get(pos) == key_to_search) {
                return pos;
            }
  
            // Incrementally construct the 
            // index of the target value 
            int new_pos = pos | (1 << i);
  
            // find the element in one 
            // direction and update position 
            if ((new_pos < n) && (A.get(new_pos) <= key_to_search)) {
                pos = new_pos;
            }
        }
  
        // if element found return pos otherwise -1 
        return ((A.get(pos) == key_to_search) ? pos : -1);
    }
  
// Driver code 
    static public void main(String[] args) {
        Vector A = new Vector();
        int[] arr = {-2, 10, 100, 250, 32315};
        for (int i = 0; i < arr.length; i++) {
            A.add(arr[i]);
        }
        System.out.println(bsearch(A, 10));
    }
}
  
// This code is contributed by 29AjayKumar
// This implementation was improved by Tanin


Python 3
# Python 3 implementation of 
# above approach
  
# Function to show the working
# of Meta binary search
import math
def bsearch(A, key_to_search):
  
    n = len(A)
    # Set number of bits to represent
    lg = int(math.log2(n-1)) + 1;
  
    # largest array index
    #while ((1 << lg) < n - 1):
        #lg += 1
  
    pos = 0
    for i in range(lg - 1, -1, -1) :
        if (A[pos] == key_to_search):
            return pos
  
        # Incrementally construct the
        # index of the target value
        new_pos = pos | (1 << i)
  
        # find the element in one
        # direction and update position
        if ((new_pos < n) and 
            (A[new_pos] <= key_to_search)):
            pos = new_pos
  
    # if element found return
    # pos otherwise -1
    return (pos if(A[pos] == key_to_search) else -1)
  
# Driver code
if __name__ == "__main__":
  
    A = [ -2, 10, 100, 250, 32315 ]
    print( bsearch(A, 10))
  
# This implementation was improved by Tanin
  
# This code is contributed
# by ChitraNayal


C#
//C# implementation of above approach 
using System;
using System.Collections.Generic;
  
class GFG 
{
  
    // Function to show the working of Meta binary search 
    static int bsearch(List A, int key_to_search)
    {
        int n = (int) A.Count;
        //int lg = 0;
        // Set number of bits to represent largest array index 
        int lg = (int)Math.Log(n-1, 2.0) + 1;
           
        // This is redundant and will cause error
        //while ((1 << lg) < n - 1)
        //{
        //    lg += 1;
        //}
  
        int pos = 0;
        for (int i = lg - 1; i >= 0; i--)
        {
            if (A[pos] == key_to_search)
            {
                return pos;
            }
  
            // Incrementally construct the 
            // index of the target value 
            int new_pos = pos | (1 << i);
  
            // find the element in one 
            // direction and update position 
            if ((new_pos < n) && (A[new_pos] <= key_to_search))
            {
                pos = new_pos;
            }
        }
  
        // if element found return pos otherwise -1 
        return ((A[pos] == key_to_search) ? pos : -1);
    }
  
    // Driver code 
    static public void Main()
    {
        List A = new List();
        int[] arr = {-2, 10, 100, 250, 32315};
        for (int i = 0; i < arr.Length; i++) 
        {
            A.Add(arr[i]);
        }
        Console.WriteLine(bsearch(A, 10));
    }
}
  
// This code is contributed by Rajput-Ji
// This implementation was improved by Tanin


PHP
= 0; $i--) 
    {
        if ($A[$pos] == $key_to_search)
            return $pos;
  
        // Incrementally construct the
        // index of the target value
        $new_pos = $pos | (1 << $i);
  
        // find the element in one
        // direction and update $position
        if (($new_pos < $n) && 
            ($A[$new_pos] <= $key_to_search))
            $pos = $new_pos;
    }
  
    // if element found return $pos 
    // otherwise -1
    return (($A[$pos] == $key_to_search) ? 
                              $pos : -1);
}
  
// Driver code
$A = [ -2, 10, 100, 250, 32315 ];
$ans = bsearch($A, 10, 5);
echo $ans;
  
// This code is contributed by AdeshSingh1
// This implementation was improved by Tanin
?>


输出:
1

参考: https //www.quora.com/What-is-meta-binary-search