按位二进制搜索算法
先决条件:二分搜索
Bitwise Binary Search算法是 Binary Search 基于以下思想的修改版本:
Every number can be represented as a sum of the powers of the number 2.
Examples:
- 76 = 64 + 8 + 4
- 10 = 8 + 2
- 7 = 4 + 2 + 1
方法:
- 计算大于或等于数组大小的 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
时间复杂度:
二分查找的时间复杂度可以写成:
T(n) = T(n/2) + c
上述递归可以使用递归树方法或主方法来解决。它属于主方法的情况 II,递归的解决方案是
辅助空间:在迭代实现的情况下为 O(1)。在递归实现的情况下,O(Logn) 递归调用堆栈空间。
算法范式:减少和征服。
笔记:
我们在这里使用
int mid = low + (high – low)/2;
也许,你想知道我们为什么要计算中间指数 这样,我们可以简单地将较低和较高的索引相加,然后除以 2。
int mid = (low + high)/2;
但是如果我们计算 像这样的中间索引意味着我们的代码不是 100% 正确的,它包含错误。
也就是说,对于较大的 int 变量 low 和 high 值,它会失败。具体来说,如果低和高的总和大于最大正 int 值(2 31 – 1 )。
总和溢出为负值,除以 2 时该值保持负数。在Java中,它抛出ArrayIndexOutOfBoundException。
int mid = low + (high – low)/2;
所以最好像这样使用它。此错误同样适用于合并排序和其他分治算法。