📜  按位二进制搜索算法

📅  最后修改于: 2022-05-13 01:56:09.149000             🧑  作者: Mango

按位二进制搜索算法

先决条件:二分搜索

Bitwise Binary Search算法是 Binary Search 基于以下思想的修改版本:

方法:

  • 计算大于或等于数组大小的 2 的第一个幂。
  • 将索引初始化为 0。
  • 在计算的功率大于 0 时循环,每次除以 2。
  • 每次位置 [index + power] <= target 的元素我们将相应的幂值添加到索引变量中。 (建立总和)
  • 在 for 循环之后检查位置 [index] 的元素是否 == 目标。如果是,则目标元素存在于数组中,否则不存在。
  • (不需要除法,只需要加法和按位移位)
C++
// C++ program to implement Bitwise Binary Search
 
#include 
 
using namespace std;
 
int binary_search(int* arr, int size, int target)
{
    int index, power;
 
    // Compute the first power of 2 that is >= size
    for (power = 1; power < size; power <<= 1)
        ;
 
    // loop while(power > 0)
    // and divide power by two each iteration
    for (index = 0; power; power >>= 1) {
 
        // if the next condition is true
        // it means that the power value can contribute to
        // the "sum"(a closer index where target might be)
        if (index + power < size
            && arr[index + power] <= target)
            index += power;
    }
 
    // if the element at position [index] == target,
    // the target value is present in the array
    if (arr[index] == target)
        return index;
 
    // else the value is not present in the array
    return -1;
}
 
int main()
{
    int arr[5] = { 1, 3, 5, 7, 8 };
    int size = 5;
    int x = 3;
    int answer = binary_search(arr, size, x);
    if (answer == -1)
        cout << "Element not found";
    else
        cout << "Element found at position " << answer;
}


Java
// Java program to implement Bitwise Binary Search
import java.util.*;
 
class GFG {
 
    static int binary_search(int[] arr, int size,
                             int target)
    {
        int index, power;
 
        // Compute the first power of 2 that is >= size
        for (power = 1; power < size; power <<= 1)
            ;
 
        // loop while(power > 0)
        // and divide power by two each iteration
        for (index = 0; power > 0; power >>= 1) {
 
            // if the next condition is true
            // it means that the power value can
            // contribute to the "sum"(a closer index where
            // target might be)
            if (index + power < size
                && arr[index + power] <= target)
                index += power;
        }
 
        // if the element at position [index] == target,
        // the target value is present in the array
        if (arr[index] == target)
            return index;
 
        // else the value is not present in the array
        return -1;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int[] arr = { 1, 3, 5, 7, 8 };
        int size = 5;
        int x = 3;
        int answer = binary_search(arr, size, x);
        if (answer == -1)
            System.out.print("Element not found");
        else
            System.out.print("Element found at position "
                             + answer);
    }
}


Python3
# Python code for the above approach
def binary_search(arr, size, target):
 
    # Compute the first power of 2 that is >= size
    power = 1
    while(power < size):
        power = power << 1
         
    # loop while(power > 0)
    # and divide power by two each iteration
    power = 1
    index = 0
    while(power):
 
        # if the next condition is true
        # it means that the power value can contribute to
        # the "sum"(a closer index where target might be)
        if (index + power < size and arr[index + power] <= target):
            index += power
        power >>= 1
 
    # if the element at position [index] == target,
    # the target value is present in the array
    if (arr[index] == target):
        return index
 
    # else the value is not present in the array
    return -1
 
arr = [1, 3, 5, 7, 8]
size = 5
x = 3
answer = binary_search(arr, size, x)
if (answer == -1):
    print("Element not found")
else:
    print(f"Element found at position {answer}")
 
# This code is contributed by gfgking


C#
// C# program to implement Bitwise Binary Search
using System;
class GFG {
    static int binary_search(int[] arr, int size,
                             int target)
    {
        int index, power;
 
        // Compute the first power of 2 that is >= size
        for (power = 1; power < size; power <<= 1)
            ;
 
        // loop while(power > 0)
        // and divide power by two each iteration
        for (index = 0; power != 0; power >>= 1) {
 
            // if the next condition is true
            // it means that the power value can contribute
            // to the "sum"(a closer index where target
            // might be)
            if (index + power < size
                && arr[index + power] <= target)
                index += power;
        }
 
        // if the element at position [index] == target,
        // the target value is present in the array
        if (arr[index] == target)
            return index;
 
        // else the value is not present in the array
        return -1;
    }
 
    public static int Main()
    {
        int[] arr = new int[] { 1, 3, 5, 7, 8 };
        int size = 5;
        int x = 3;
        int answer = binary_search(arr, size, x);
        if (answer == -1)
            Console.Write("Element not found");
        else
            Console.Write("Element found at position "
                          + answer);
        return 0;
    }
}
 
// This code is contributed by Taranpreet


Javascript



输出
Element found at position 1

时间复杂度: Theta(Logn)

二分查找的时间复杂度可以写成:

上述递归可以使用递归树方法或主方法来解决。它属于主方法的情况 II,递归的解决方案是Theta(Logn)

辅助空间:在迭代实现的情况下为 O(1)。在递归实现的情况下,O(Logn) 递归调用堆栈空间。

算法范式:减少和征服。

笔记:

我们在这里使用

也许,你想知道我们为什么要计算中间指数 这样,我们可以简单地将较低和较高的索引相加,然后除以 2。

但是如果我们计算 像这样的中间索引意味着我们的代码不是 100% 正确的,它包含错误。

也就是说,对于较大的 int 变量 low 和 high 值,它会失败。具体来说,如果低和高的总和大于最大正 int 值(2 31 – 1 )。

总和溢出为负值,除以 2 时该值保持负数。在Java中,它抛出ArrayIndexOutOfBoundException。

所以最好像这样使用它。此错误同样适用于合并排序和其他分治算法。