Home C++ C++ Random Access Iterators tutorials with code examples

C++ Random Access Iterators tutorials with code examples

In C++, Random Access Iterators are the most powerful type of iterators that allow direct access to any element in a container by using an index.

They enable both sequential and non-sequential access, making them ideal for algorithms that require fast and flexible navigation of elements.

Random access iterators are used in containers like std::vector, std::deque, and std::array.

Characteristics of Random Access Iterators

  1. Bidirectional and random access: Can move both forward and backward and jump to any element.
  2. Constant-time element access: Support direct access using an offset.
  3. Arithmetic operations: Support addition (+) and subtraction (-) of integers.
  4. Relational comparisons: Can be compared using <, <=, >, and >=.
  5. Multi-pass: Can iterate over the same range multiple times.

1. Basic Example of Random Access Iterator with std::vector

The std::vector container uses random access iterators, allowing you to directly access elements by their index.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> numbers = {10, 20, 30, 40, 50};

    // Access elements using random access iterator
    auto it = numbers.begin();

    cout << "First element: " << *it << endl;
    cout << "Third element (using offset): " << *(it + 2) << endl;

    return 0;
}

Explanation:

  • it + 2 accesses the third element in the vector by moving the iterator forward by 2 positions.

Output:

First element: 10
Third element (using offset): 30

2. Using Arithmetic Operations with Random Access Iterators

Random access iterators support addition and subtraction, enabling quick jumps to any position within the container.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> numbers = {5, 10, 15, 20, 25, 30};

    auto it = numbers.begin();
    it += 3; // Move iterator 3 positions forward

    cout << "Element at position 4: " << *it << endl;

    it -= 2; // Move iterator 2 positions backward
    cout << "Element at position 2: " << *it << endl;

    return 0;
}

Explanation:

  • it += 3 moves the iterator to the fourth element.
  • it -= 2 moves it backward to the second element.

Output:

Element at position 4: 20
Element at position 2: 10

3. Comparing Random Access Iterators

Random access iterators support relational operators, allowing you to compare positions within the container.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> numbers = {1, 2, 3, 4, 5};

    auto it1 = numbers.begin();
    auto it2 = numbers.end() - 1; // Last element

    if (it1 < it2) {
        cout << "it1 points to an earlier position than it2." << endl;
    }

    return 0;
}

Explanation:

  • it1 < it2 checks if it1 is positioned before it2, which is true in this example.

Output:

it1 points to an earlier position than it2.

4. Calculating Distance Between Random Access Iterators

The std::distance function calculates the number of elements between two iterators, and for random access iterators, it operates in constant time.

#include <iostream>
#include <vector>
#include <iterator>
using namespace std;

int main() {
    vector<int> numbers = {10, 20, 30, 40, 50};

    auto it1 = numbers.begin();
    auto it2 = numbers.end();

    cout << "Distance between it1 and it2: " << distance(it1, it2) << endl;

    return 0;
}

Explanation:

  • distance(it1, it2); returns the number of elements between it1 and it2.

Output:

Distance between it1 and it2: 5

5. Accessing Elements Using [] Operator

The [] operator is unique to random access iterators, allowing direct indexing similar to arrays.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> numbers = {100, 200, 300, 400, 500};

    auto it = numbers.begin();

    cout << "Second element using []: " << it[1] << endl;
    cout << "Fourth element using []: " << it[3] << endl;

    return 0;
}

Explanation:

  • it[1] and it[3] directly access the second and fourth elements, respectively.

Output:

Second element using []: 200
Fourth element using []: 400

6. Reversing Elements with std::reverse and Random Access Iterators

The std::reverse function uses random access iterators to reverse a container’s elements.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> numbers = {1, 2, 3, 4, 5};

    // Reverse the vector
    reverse(numbers.begin(), numbers.end());

    cout << "Reversed elements: ";
    for (int number : numbers) {
        cout << number << " ";
    }

    return 0;
}

Explanation:

  • reverse(numbers.begin(), numbers.end()); reverses the entire vector.

Output:

Reversed elements: 5 4 3 2 1

7. Using std::sort with Random Access Iterators

The std::sort algorithm uses random access iterators to sort elements in ascending order.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> numbers = {30, 10, 40, 20, 50};

    // Sort the vector
    sort(numbers.begin(), numbers.end());

    cout << "Sorted elements: ";
    for (int number : numbers) {
        cout << number << " ";
    }

    return 0;
}

Explanation:

  • sort(numbers.begin(), numbers.end()); sorts numbers in ascending order.

Output:

Sorted elements: 10 20 30 40 50

8. Accessing Last Element with Random Access Iterator and end() – 1

Random access iterators make it easy to access the last element using end() – 1.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> numbers = {100, 200, 300, 400, 500};

    auto it = numbers.end() - 1; // Points to the last element
    cout << "Last element: " << *it << endl;

    return 0;
}

Explanation:

  • numbers.end() – 1 provides a random access iterator pointing to the last element in numbers.

Output:

Last element: 500

9. Generating Sequence with std::generate and Random Access Iterators

The std::generate function fills a container with generated values using random access iterators.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> numbers(5);

    // Fill vector with incrementing numbers starting from 1
    int start = 1;
    generate(numbers.begin(), numbers.end(), [&]() { return start++; });

    cout << "Generated sequence: ";
    for (int number : numbers) {
        cout << number << " ";
    }

    return 0;
}

Explanation:

  • generate fills numbers with values from a lambda function, creating a sequence from 1 to 5.

Output:

Generated sequence: 1 2 3 4 5

10. Using std::binary_search with Sorted Vector

The std::binary_search function takes random access iterators to quickly search for elements in a sorted container.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> numbers = {10, 20, 30, 40, 50};

    // Perform binary search for 30
    if (binary_search(numbers.begin(), numbers.end(), 30)) {
        cout << "Element 30 found!" << endl;
    } else {
        cout << "Element not found!" << endl;
    }

    return 0;
}

Explanation:

  • binary_search(numbers.begin(), numbers.end(), 30); quickly checks if 30 is present in the sorted vector numbers.

Output:

Element 30 found!

Summary Table of Random Access Iterator Usage

Example Description
Basic Vector Access Accesses elements by index using it + offset
Using Arithmetic Operations Moves iterator forward and backward
Comparing Iterators Compares iterator positions using relational operators
Calculating Distance Calculates number of elements between two iterators
Accessing Elements with [] Directly accesses elements with the [] operator
Reversing Elements Reverses container elements with std::reverse
Sorting Elements Sorts container with std::sort
Accessing Last Element Accesses the last element using end() – 1
Generating Sequence Fills container with generated values using std::generate
Binary Search Performs binary search on sorted container with std::binary_search

Key Takeaways

  • Random Access Iterators allow fast, direct access to any position in a container.
  • They support arithmetic operations (+, -) and random indexing ([]), making them versatile for complex data manipulations.
  • Containers like std::vector, std::deque, and std::array provide random access iterators.
  • Algorithms like std::sort, std::reverse, std::binary_search, and std::generate can efficiently work with random access iterators, enabling powerful and efficient operations on data.

You may also like