HOWTO · C++

How to Shuffle Vector in C++

This article introduces how to shuffle a vector in C++

On this page

To randomly reorder the elements of a C++ vector in place, call std::shuffle with the vector’s begin() and end() iterators and a random-number engine. The algorithm rearranges the elements in the supplied range; it does not create a second vector. Use a fixed engine seed when you want a repeatable sequence of pseudo-random choices, or seed the engine from an appropriate source when you want different runs to usually produce different sequences.

Shuffle a vector with std::shuffle

std::shuffle is declared in the <algorithm> header. Its first two arguments delimit a half-open iterator range: the first iterator points to the first element to include, and the second points just past the last element. For a vector, values.begin() and values.end() therefore cover the whole vector. The third argument is a UniformRandomBitGenerator, commonly an engine such as std::mt19937. The engine supplies the random bits used to choose the permutation; it is not a callback that returns an already-shuffled vector.

This complete example uses a fixed seed so that the engine starts from the same state each time the program runs. The particular shuffled order is not promised by std::shuffle: it can vary with the standard-library implementation, so treat the output below as one example rather than a guaranteed sequence.

Run this example:

#include <algorithm>
#include <cstddef>
#include <iostream>
#include <random>
#include <vector>

int main() {
    std::vector<int> values{12, 32, 43, 53, 23, 65, 84};
    std::mt19937 engine(42);

    std::shuffle(values.begin(), values.end(), engine);

    for (std::size_t i = 0; i < values.size(); ++i) {
        if (i != 0) {
            std::cout << ' ';
        }
        std::cout << values[i];
    }
    std::cout << '\n';
}

The input vector is 12 32 43 53 23 65 84. In the supplied successful run, the program printed this shuffled order:

23 12 43 53 84 65 32

A fixed seed makes the pseudo-random engine’s sequence reproducible within the same implementation and setup. It does not guarantee identical shuffled output across all standard-library implementations, because the algorithm’s exact choices are not specified as one universal sequence. For varying runs, seed an engine once, then reuse it for shuffles rather than constructing a new engine for each element or each call. std::random_device is often used as a seed source, but its behavior depends on the implementation and environment; it should not be described as a guarantee of nondeterminism or cryptographic randomness.

You can also express the range with std::begin(values) and std::end(values), available through the standard iterator utilities. This form is useful when writing a generic helper that accepts different container types or built-in arrays. For a vector-specific call, its member iterators are direct and clear. In either form, pass both endpoints from the same container, and make sure the range contains the elements you intend to permute. The operation changes the vector’s order in place, so later code that reads or iterates over it sees the shuffled arrangement.

Handle legacy code that uses std::random_shuffle

std::random_shuffle is an older standard-library algorithm that may appear in existing C++ code. Its availability depends on the language standard selected by the project and the library implementation being used. When maintaining such code, check those settings before assuming the name is available. The older overloads may use an implementation-defined source of randomness, while overloads accepting a generator have different requirements from the engine argument used by std::shuffle.

For new or updated code, prefer std::shuffle and pass an explicit random engine. This makes the source of randomness visible, gives you a way to control repeatability with a seed, and avoids depending on the older interface. Do not infer from the presence of std::random_shuffle in a codebase that it is available in every compiler mode, or that every older environment lacks std::shuffle; compatibility is determined by the project’s standard-library and language-standard configuration. If a project must retain legacy code, keep its compatibility choice local to that project and verify it with the compiler configuration used to build it.