How to resolve the algorithm Binary search step by step in the C++ programming language
How to resolve the algorithm Binary search step by step in the C++ programming language
Table of Contents
Problem Statement
A binary search divides a range of values into halves, and continues to narrow down the field of search until the unknown value is found. It is the classic example of a "divide and conquer" algorithm. As an analogy, consider the children's game "guess a number." The scorer has a secret number, and will only tell the player if their guessed number is higher than, lower than, or equal to the secret number. The player then uses this information to guess a new number. As the player, an optimal strategy for the general case is to start by choosing the range's midpoint as the guess, and then asking whether the guess was higher, lower, or equal to the secret number. If the guess was too high, one would select the point exactly between the range midpoint and the beginning of the range. If the original guess was too low, one would ask about the point exactly between the range midpoint and the end of the range. This process repeats until one has reached the secret number.
Given the starting point of a range, the ending point of a range, and the "secret value", implement a binary search through a sorted integer array for a certain number. Implementations can be recursive or iterative (both if you can). Print out whether or not the number was in the array afterwards. If it was, print the index also. There are several binary search algorithms commonly seen. They differ by how they treat multiple values equal to the given value, and whether they indicate whether the element was found or not. For completeness we will present pseudocode for all of them. All of the following code examples use an "inclusive" upper bound (i.e. high = N-1 initially). Any of the examples can be converted into an equivalent example using "exclusive" upper bound (i.e. high = N initially) by making the following simple changes (which simply increase high by 1): The algorithms are as follows (from Wikipedia). The algorithms return the index of some element that equals the given value (if there are multiple such elements, it returns some arbitrary one). It is also possible, when the element is not found, to return the "insertion point" for it (the index that the value would have if it were inserted into the array). Recursive Pseudocode: Iterative Pseudocode: The following algorithms return the leftmost place where the given element can be correctly inserted (and still maintain the sorted order). This is the lower (inclusive) bound of the range of elements that are equal to the given value (if any). Equivalently, this is the lowest index where the element is greater than or equal to the given value (since if it were any lower, it would violate the ordering), or 1 past the last index if such an element does not exist. This algorithm does not determine if the element is actually found. This algorithm only requires one comparison per level. Recursive Pseudocode: Iterative Pseudocode: The following algorithms return the rightmost place where the given element can be correctly inserted (and still maintain the sorted order). This is the upper (exclusive) bound of the range of elements that are equal to the given value (if any). Equivalently, this is the lowest index where the element is greater than the given value, or 1 past the last index if such an element does not exist. This algorithm does not determine if the element is actually found. This algorithm only requires one comparison per level. Note that these algorithms are almost exactly the same as the leftmost-insertion-point algorithms, except for how the inequality treats equal values. Recursive Pseudocode: Iterative Pseudocode: Make sure it does not have overflow bugs. The line in the pseudo-code above to calculate the mean of two integers: could produce the wrong result in some programming languages when used with a bounded integer type, if the addition causes an overflow. (This can occur if the array size is greater than half the maximum integer value.) If signed integers are used, and low + high overflows, it becomes a negative number, and dividing by 2 will still result in a negative number. Indexing an array with a negative number could produce an out-of-bounds exception, or other undefined behavior. If unsigned integers are used, an overflow will result in losing the largest bit, which will produce the wrong result. One way to fix it is to manually add half the range to the low number: Even though this is mathematically equivalent to the above, it is not susceptible to overflow. Another way for signed integers, possibly faster, is the following: where >>> is the logical right shift operator. The reason why this works is that, for signed integers, even though it overflows, when viewed as an unsigned number, the value is still the correct sum. To divide an unsigned number by 2, simply do a logical right shift.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Binary search step by step in the C++ programming language
Source Code Explanation
The provided source code includes two implementations of a binary search algorithm and several examples of searching for elements in an array using the std::
library's algorithms for binary search:
1. Template Function 'binsearch'
This function implements a generic binary search for an array sorted in ascending order. It takes the following parameters:
const T array[]
: The sorted array to searchint low
: The lower bound of the search rangeint high
: The upper bound of the search rangeT value
: The value to search for
The function recursively partitions the search range in half and compares the value to the element in the middle. It adjusts the search range based on whether the value is less than or greater than the middle element. If the value is found, it returns the index; otherwise, it returns -1.
2. Template Function 'binSearch'
This function is another implementation of binary search that works similarly to the first function. It takes the following parameters:
const T arr[]
: The sorted array to searchint len
: The length of the arrayT what
: The value to search for
The function uses a while loop to repeatedly narrow down the search range until either the value is found or the range becomes empty.
3. std::lower_bound
and std::upper_bound
These functions from the std
library perform a binary search and return iterators pointing to the first element that is greater than or equal to (std::lower_bound
) or greater than (std::upper_bound
) the specified value, respectively.
4. std::equal_range
This function performs a binary search and returns a pair of iterators that define the range of elements that are equal to the specified value.
5. std::binary_search
This function performs a binary search and returns a boolean value indicating whether the specified value is found in the array.
Example Usage
The main function demonstrates the usage of the different search methods. It searches for the values 4 and 8 in the array array
. The results are printed to the console, indicating whether the elements were found and at what index.
Additional Notes:
- The
binsearch
andbinSearch
functions are generic and can be used with any type of array that supports comparison. - The
std::
library functions take advantage of the compiler's ability to deduce the type of the array and the value to search for, eliminating the need to specify them explicitly. - Binary search is an efficient algorithm for searching sorted arrays and has a time complexity of O(log n), where n is the number of elements in the array.
Source code in the cpp programming language
template <class T> int binsearch(const T array[], int low, int high, T value) {
if (high < low) {
return -1;
}
auto mid = (low + high) / 2;
if (value < array[mid]) {
return binsearch(array, low, mid - 1, value);
} else if (value > array[mid]) {
return binsearch(array, mid + 1, high, value);
}
return mid;
}
#include <iostream>
int main()
{
int array[] = {2, 3, 5, 6, 8};
int result1 = binsearch(array, 0, sizeof(array)/sizeof(int), 4),
result2 = binsearch(array, 0, sizeof(array)/sizeof(int), 8);
if (result1 == -1) std::cout << "4 not found!" << std::endl;
else std::cout << "4 found at " << result1 << std::endl;
if (result2 == -1) std::cout << "8 not found!" << std::endl;
else std::cout << "8 found at " << result2 << std::endl;
return 0;
}
template <class T>
int binSearch(const T arr[], int len, T what) {
int low = 0;
int high = len - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (arr[mid] > what)
high = mid - 1;
else if (arr[mid] < what)
low = mid + 1;
else
return mid;
}
return -1; // indicate not found
}
#include <algorithm>
int *ptr = std::lower_bound(array, array+len, what); // a custom comparator can be given as fourth arg
int *ptr = std::upper_bound(array, array+len, what); // a custom comparator can be given as fourth arg
std::pair<int *, int *> bounds = std::equal_range(array, array+len, what); // a custom comparator can be given as fourth arg
bool found = std::binary_search(array, array+len, what); // a custom comparator can be given as fourth arg
You may also check:How to resolve the algorithm Roman numerals/Encode step by step in the Common Lisp programming language
You may also check:How to resolve the algorithm List comprehensions step by step in the Sidef programming language
You may also check:How to resolve the algorithm Anagram generator step by step in the Nim programming language
You may also check:How to resolve the algorithm Integer sequence step by step in the Yabasic programming language
You may also check:How to resolve the algorithm ABC problem step by step in the D programming language