Open In App

Binary Search functions in C++ STL (binary_search, lower_bound and upper_bound)

Last Updated : 20 Jun, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Binary search is an important component in competitive programming or any algorithmic competition, having knowledge of shorthand functions reduces the time to code them. Binary search is the most efficient search algorithm.

Binary Search is a searching algorithm used in a sorted array by repeatedly dividing the search interval in half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(Log N). 

General operations performed using binary search:

  1. finding an element
  2. lower_bound 
  3. upper_bound

1. binary_search:

binary_search(start_ptr, end_ptr, num): This function returns true if the element is present in the container, else returns false. The start_ptr variable holds the starting point of the binary search and end_ptr holds the ending position of binary search space and num is the value to be found.

Coding implementation of binary_search function: 

CPP




// C++ code to demonstrate the working of binary_search()
 
#include <bits/stdc++.h>
using namespace std;
 
// Driver's code
int main()
{
    // initializing vector of integers
    vector<int> arr = { 10, 15, 20, 25, 30, 35 };
 
    // using binary_search to check if 15 exists
    if (binary_search(arr.begin(), arr.end(), 15))
        cout << "15 exists in vector";
    else
        cout << "15 does not exist";
 
    cout << endl;
 
    // using binary_search to check if 23 exists
    if (binary_search(arr.begin(), arr.end(), 23))
        cout << "23 exists in vector";
    else
        cout << "23 does not exist";
 
    cout << endl;
}


Output

15 exists in vector
23 does not exist

Time Complexity: O(log N) – where N is the number of elements in the array.
Auxiliary Space: O(1)

2. lower_bound:

lower_bound(start_ptr, end_ptr, num):Returns pointer to the position of num if the container contains only one occurrence of num. Returns a pointer to the first position of num if the container contains multiple occurrences of num. Returns pointer to the position of a number just higher than num, if the container does not contain an occurrence of num which is the position of the number when inserted in the already sorted array and sorted again. Subtracting the first position i.e vect.begin() from the pointer, returns the actual index. The start_ptr variable holds the starting point of the binary search and end_ptr holds the ending position of binary search space and num is the value to be found.

Coding implementation of lower_bound function:

CPP




// C++ code to demonstrate the working of lower_bound()
#include <bits/stdc++.h>
using namespace std;
 
// Driver's code
int main()
{
    // initializing vector of integers
    // for single occurrence
    vector<int> arr1 = { 10, 15, 20, 25, 30, 35 };
 
    // initializing vector of integers
    // for multiple occurrences
    vector<int> arr2 = { 10, 15, 20, 20, 25, 30, 35 };
 
    // initializing vector of integers
    // for no occurrence
    vector<int> arr3 = { 10, 15, 25, 30, 35 };
 
    // using lower_bound() to check if 20 exists
    // single occurrence
    // prints 2
    cout << "The position of 20 using lower_bound "
            " (in single occurrence case) : ";
    cout << lower_bound(arr1.begin(), arr1.end(), 20)
                - arr1.begin();
 
    cout << endl;
 
    // using lower_bound() to check if 20 exists
    // multiple occurrence
    // prints 2
    cout << "The position of 20 using lower_bound "
            "(in multiple occurrence case) : ";
    cout << lower_bound(arr2.begin(), arr2.end(), 20)
                - arr2.begin();
 
    cout << endl;
 
    // using lower_bound() to check if 20 exists
    // no occurrence
    // prints 2 ( index of next higher)
    cout << "The position of 20 using lower_bound "
            "(in no occurrence case) : ";
    cout << lower_bound(arr3.begin(), arr3.end(), 20)
                - arr3.begin();
 
    cout << endl;
}


Output

The position of 20 using lower_bound  (in single occurrence case) : 2
The position of 20 using lower_bound (in multiple occurrence case) : 2
The position of 20 using lower_bound (in no occurrence case) : 2

Time Complexity: O(log N) – where N is the number of elements in the array.
Auxiliary Space: O(1)

3. upper_bound:

upper_bound(start_ptr, end_ptr, num): Returns pointer to the position of next higher number than num if the container contains one occurrence of num. Returns pointer to the first position of the next higher number than the last occurrence of num if the container contains multiple occurrences of num. Returns pointer to position of next higher number than num if the container does not contain an occurrence of num. Subtracting the first position i.e vect.begin() from the pointer, returns the actual index. The start_ptr variable holds the starting point of the binary search and end_ptr holds the ending position of binary search space and num is the value to be found.

Coding implementation of upper_bound function:

CPP




// C++ code to demonstrate the working of upper_bound()
#include <bits/stdc++.h>
using namespace std;
 
// Driver's code
int main()
{
    // initializing vector of integers
    // for single occurrence
    vector<int> arr1 = { 10, 15, 20, 25, 30, 35 };
 
    // initializing vector of integers
    // for multiple occurrences
    vector<int> arr2 = { 10, 15, 20, 20, 25, 30, 35 };
 
    // initializing vector of integers
    // for no occurrence
    vector<int> arr3 = { 10, 15, 25, 30, 35 };
 
    // using upper_bound() to check if 20 exists
    // single occurrence
    // prints 3
    cout << "The position of 20 using upper_bound"
            " (in single occurrence case) : ";
    cout << upper_bound(arr1.begin(), arr1.end(), 20)
                - arr1.begin();
 
    cout << endl;
 
    // using upper_bound() to check if 20 exists
    // multiple occurrence
    // prints 4
    cout << "The position of 20 using upper_bound "
            "(in multiple occurrence case) : ";
    cout << upper_bound(arr2.begin(), arr2.end(), 20)
                - arr2.begin();
 
    cout << endl;
 
    // using upper_bound() to check if 20 exists
    // no occurrence
    // prints 2 ( index of next higher)
    cout << "The position of 20 using upper_bound"
            " (in no occurrence case) : ";
    cout << upper_bound(arr3.begin(), arr3.end(), 20)
                - arr3.begin();
 
    cout << endl;
}


Output

The position of 20 using upper_bound (in single occurrence case) : 3
The position of 20 using upper_bound (in multiple occurrence case) : 4
The position of 20 using upper_bound (in no occurrence case) : 2

Time Complexity: O(log N) – where N is the number of elements in the array.
Auxiliary Space: O(1)

 



Previous Article
Next Article

Similar Reads

std::upper_bound and std::lower_bound for Vector in C++ STL
Click here for Set 1 and Set 2 of Vectors. Vector - upper_bound and lower_boundIterator lower_bound (Iterator first, Iterator last, const val) lower_bound returns an iterator pointing to the first element in the range [first,last) which has a value not less than 'val' and if the value is not present in the vector then it returns the end iterator. I
4 min read
GFact | Why s.lower_bound(x) is faster than lower_bound(s.begin(), s.end(), x) in C++ STL?
Have you ever got TLE on solving a question using function lower_bound (s.begin(), s.end(), x) and when you use s.lower_bound(x) it runs just fine (here s is a Data structure and x is the value we are searching for) !! If "Yes" then why this happens? Well, we are going to find out this in the following article, but before that let's know about the
4 min read
Search String using binary_search() function in C++ STL
The in-built STL library function binary_search() for searching whether a given string is present or not in the given string array. Binary search is a divide and conquers approach. The idea behind the binary search algorithm is to keep dividing the array in half until the element is found, or all the elements are exhausted. The middle item of the a
2 min read
Difference between std::set::upper_bound and std::upper_bound in C++
Prerequisites: Random-access Iterators, Bidirectional Iterators Sets are a type of associative container in which each element has to be unique because the value of the element identifies it. The value of the element cannot be modified once it is added to the set, though it is possible to remove and add the modified value of that element. Functions
4 min read
Implementing upper_bound() and lower_bound() for Ordered Set in C++
Prerequisites: Ordered Set and GNU C++ PBDS Given an ordered set set and a key K, the task is to find the upper bound and lower bound of the element K in the set in C++. If the element is not present or either of the bounds could not be calculated, then print -1. Ordered set is a policy based data structure in g++ that keeps the unique elements in
3 min read
Implementation of lower_bound() and upper_bound() in Vector of Pairs in C++
Here we will discuss the implementation of the lower_bound() and upper_bound() in vector of pairs. lower_bound(): It returns an iterator pointing to the first element in the range [first, last) which has a value greater than or equal to the given value "val". But in Vector of Pairs lower_bound() for pair(x, y) will return an iterator pointing to th
3 min read
Implementation of lower_bound and upper_bound on Set of Pairs in C++
Prerequisite: set lower_bound() function in C++ STL, set upper_bound() function in C++ STL lower_bound() returns an iterator pointing to the first element in the range [first, last) which has a value greater than or equals to the given value "val". But in set of Pairs lower_bound() for pair(x, y) will return an iterator pointing to the position of
3 min read
Implementation of lower_bound() and upper_bound() on Map of Pairs in C++
Prerequisite: map lower_bound() function in C++ STL, map upper_bound() function in C++ STL In this article, we will discuss the implementation of the lower_bound() and upper_bound() in the Map of pairs. lower_bound(): It returns an iterator pointing to the first element in the range [first, last) which has a value greater than or equals to the give
3 min read
Implementation of lower_bound() and upper_bound() in List of Pairs in C++
In this article, we will discuss the implementation of the lower_bound() and upper_bound() in a list of pairs. lower_bound(): It returns an iterator pointing to the first element in the range [first, last) which has a value greater than or equals to the given value “val”. But in List of Pairs lower_bound() for pair(x, y) will return an iterator poi
3 min read
Difference between std::set::lower_bound and std::lower_bound in C++
Prerequisite: Random-access Iterators in C++, Bidirectional Iterators in C++. std::lower_bound in C++: The lower_bound() method in C++ is used to return an iterator pointing to the first element in the range [first, last) which has a value not less than the given value. This means that the function returns the index of the next smallest number just
4 min read
three90RightbarBannerImg