Fisher-Yates shuffle algorithm
Fisher-Yates Shuffle Algorithm Explained: How Fair Randomization Works
Learn how the Fisher-Yates shuffle algorithm works, why it produces unbiased random permutations, how to implement it, and how it helps create fair groups.

Imagine you have 30 students and need to divide them into five groups. You want every student to have an equal opportunity to end up in any group, without repeatedly favoring the people whose names appear first on your list. Simply rearranging names by hand can introduce patterns, while an incorrectly written computer program can produce results that look random but are actually biased. The Fisher-Yates shuffle algorithm solves this problem by providing a structured way to randomly rearrange a list. It is useful for understanding how fair randomization works in classrooms, workshops, team activities, and software applications.
What Is the Fisher-Yates Shuffle Algorithm?
The Fisher-Yates shuffle algorithm is a method for generating a random permutation of a collection of items. A permutation is simply a particular arrangement of the same items. If you start with five names, for example, a permutation changes their order without adding or removing anyone.
The algorithm works by selecting an item from the portion of the list that has not yet been shuffled and exchanging it with the item at the current position. It repeats this process until every position is determined. The result is a rearranged list in which every possible ordering has an equal probability, provided that each random selection is uniform and independent.
The original method was described by statisticians Ronald Fisher and Frank Yates in 1938. Richard Durstenfeld later introduced an efficient version in 1964 that rearranges elements directly within an array. This modern version is also commonly called the Knuth shuffle because of its popularity in computer science literature.
For educators and facilitators, the important idea is straightforward: instead of choosing items without a consistent process, the algorithm uses a clearly defined sequence of random decisions. This makes it easier to understand, implement, and test random assignments.
How the Fisher-Yates Shuffle Algorithm Works
The easiest way to understand the algorithm is to imagine shuffling a deck of cards. Rather than repeatedly selecting cards from the entire deck, you progressively choose from the cards that have not yet been placed in their final positions.
The modern version usually works backward through an array. At each step, it selects a random position from the beginning of the remaining unshuffled portion and swaps that item with the current position.

Here is the process using a list of six students:
- Start with the original list: Anna, Ben, Chloe, David, Emma, and Frank.
- Begin at the last position, occupied by Frank.
- Choose a random index from all six available positions.
- Swap the selected student with Frank.
- Move one position to the left and choose randomly from the five positions that remain available.
- Repeat the selection and swapping process until only one position remains.
- Treat the resulting arrangement as the shuffled list.
Notice that the selection range becomes smaller after every swap. Once an item reaches its final position, the algorithm does not select it again during later iterations.
This detail is essential. It means that each step makes a decision using only the remaining available positions. The algorithm does not need to repeatedly check whether an item has already been selected.
For a classroom example, imagine preparing a randomized presentation order for six students. After shuffling the names, you can use the resulting sequence to decide who presents first, second, and so on. Everyone appears exactly once, and the ordering is not determined by the original alphabetical list.
Understanding the Algorithm With Pseudocode
Pseudocode describes the logic of an algorithm without requiring a specific programming language. The modern Fisher-Yates method can be written in a few simple steps.
text
FisherYatesShuffle(array):
n = length(array)
for i from n - 1 down to 1:
j = random integer between 0 and i
swap array[i] with array[j]
return array
There are three important details to understand.
First, the loop starts at the last index, which is n - 1 because most programming languages use zero-based indexing. Second, the random index j must be selected from zero through i, including both endpoints. Third, the two selected elements are exchanged rather than copied or removed.
For example, consider this list:
text
Before: [A, B, C, D]
Suppose the random selections produce the following swaps:
text
Step 1: i = 3, j = 1
[A, D, C, B]
Step 2: i = 2, j = 0
[C, D, A, B]
Step 3: i = 1, j = 1
[C, D, A, B]
The final arrangement is [C, D, A, B]. Notice that selecting the current position is allowed. A swap does not always have to change the arrangement.
This example also shows why the algorithm is practical: it can rearrange an entire list using a small number of straightforward operations. There is no requirement to build a separate collection of selected items.
Why Does the Fisher-Yates Shuffle Produce Fair Results?
A random-looking result is not necessarily a fair result. A list might look different every time it is shuffled while still favoring certain arrangements. To understand why Fisher-Yates works, consider how many choices are available at each step.
For a list containing four distinct items, the algorithm makes three random selections:
- The first selection has four possible positions.
- The second selection has three possible positions.
- The third selection has two possible positions.
The final item occupies the remaining position automatically. Therefore, the total number of possible decision sequences is:
\[4 \times 3 \times 2 = 24\]
There are also exactly 24 possible permutations of four distinct items. Each possible final arrangement corresponds to exactly one sequence of valid choices. When every choice is uniform and independent, each arrangement therefore has the same probability:
\[P(\text{particular arrangement}) = \frac{1}{n!}\]
For four items, that probability is 1/24. This mathematical property is called a uniform distribution over permutations.

This matters in real activities. Suppose a teacher has 24 students and wants to create groups without favoring students whose names appear near the beginning of a roster. A correctly implemented shuffle gives every student an equal probability of occupying each position in the shuffled sequence.
However, fair shuffling does not automatically guarantee perfectly balanced groups. If students have different skill levels, experience, or support requirements, additional grouping rules may be needed. Randomization determines the order fairly; group composition still depends on how that order is divided.
Common Mistakes That Make a Shuffle Biased
One of the most common programming mistakes is selecting a random position from the entire list during every iteration. This may seem reasonable because every element has an opportunity to move. However, it does not follow the shrinking selection range required by Fisher-Yates.
Another mistake is using a random number without correctly restricting its range. At iteration i, the selected index must be between zero and i, inclusive. Choosing an index outside this range can interfere with the algorithm's guarantee that completed positions stay fixed.
Here are several mistakes worth checking when reviewing an implementation:
- Using the wrong random range: The upper boundary must change with the current index.
- Skipping the current position: The selected item must be allowed to swap with itself.
- Shuffling only part of the list: Every required position must be processed.
- Using an unsuitable random number conversion: Modulo operations can introduce bias when the random source's possible values do not divide evenly into the desired range.
- Confusing randomness with balance: A fair shuffle does not guarantee equal group sizes or balanced abilities.
For example, consider a trainer who assigns 20 employees to four workshop teams. A flawed shuffle might repeatedly favor certain list positions. If the same employees regularly appear near the beginning of the original roster, they may receive predictable assignments under an unsuitable implementation.
The solution is to use a well-tested shuffle implementation or carefully verify the random index range and swapping procedure. When implementing a shuffle yourself, review both the algorithm and the random number generator that supplies its selections.
Time Complexity and Practical Performance
The modern Fisher-Yates shuffle has a time complexity of O(n), where n represents the number of elements in the list. This means the number of operations grows approximately in proportion to the number of items being shuffled.
It also uses O(1) auxiliary space when implemented directly on a random-access array, because it swaps elements within the existing collection rather than creating another full-size collection. These properties make it suitable for lists containing students, employees, participants, or other records.
Compare this with a simple approach that assigns every item a random number and then sorts the list by those numbers. That approach generally requires sorting, which takes O(n log n) time with an efficient comparison sort. It also requires additional consideration of ties and random number quality.
For a teacher shuffling a list of 25 students, either approach may feel fast. However, when an application needs to shuffle thousands of records repeatedly, the linear-time approach offers a clear computational advantage.
There is an important practical qualification: O(n) describes the algorithm's operations, not every possible source of randomness. Generating random values also has a cost, and the quality of those values affects the fairness of the final result.
Using Random Shuffling to Create Fair Classroom and Workplace Groups
Understanding randomization is useful beyond programming. Teachers and facilitators regularly need to distribute participants into pairs, small teams, presentation orders, or activity stations. A shuffled list provides a simple foundation for these tasks.
For example, imagine a teacher preparing a science activity for 28 students. The teacher wants four-person teams and does not want to manually assign students based on their seating positions. A shuffled list can be divided into consecutive blocks of four, producing seven teams.
A practical workflow looks like this:
- Prepare a complete list of participants.
- Check that every participant appears once and that names are distinguishable.
- Shuffle the list using a reliable randomization method.
- Decide the number of teams or the desired team size.
- Divide the shuffled sequence into groups.
- Review the results for practical constraints, such as accessibility needs or required team roles.

If you want to create teams without manually writing code, the Random Group Generator provides a practical way to organize participant lists into groups. For activities that require exactly two participants per team, the Random Pair Generator is another useful option.
The distinction between shuffling and grouping is important. A shuffle rearranges the participants, while a grouping tool applies an additional rule to divide them. Depending on the activity, you might want equal group sizes, a fixed number of teams, or pairs rather than larger groups.
For instance, a corporate trainer running a communication workshop might use pairs for short discussions and groups of four for a later problem-solving exercise. Choosing the appropriate grouping format makes the activity easier to manage.
Randomization also has limits. It does not account automatically for student ability, language needs, previous collaboration, or workplace reporting relationships. When these factors matter, facilitators should apply appropriate constraints or review the results before beginning the activity.
How to Test Whether a Shuffle Is Working Correctly
A single shuffled result cannot prove that an algorithm is unbiased. A correct shuffle can produce an arrangement that looks surprising, repetitive, or similar to the original list. Randomness does not mean every result must look dramatically different.
A useful way to test an implementation is to run it repeatedly with a small collection of distinct items and record the resulting permutations. For three items, there are six possible arrangements. Across many independent trials, you can examine whether the results show obvious patterns or whether particular arrangements appear disproportionately often.
You can also test individual positions. For example, if you shuffle three distinct items repeatedly, each item should have an equal probability of appearing in the first position under the ideal model. Similar checks can be performed for the second and third positions.
A basic testing workflow is:
- Create a small list containing distinct values.
- Run the shuffle many times using independent random selections.
- Count how often each possible arrangement appears.
- Compare the observed frequencies with the expected distribution.
- Investigate unusual patterns and inspect the random index selection logic.
Statistical testing is useful for identifying problems, but it cannot establish mathematical correctness on its own. A small test might fail to reveal a subtle bias, while an occasional uneven result is expected even with a correct algorithm.
For applications involving ordinary classroom or workshop assignments, a standard, well-tested randomization library is usually a sensible choice. For security-sensitive applications, a separate review of the random number generator and security requirements is necessary.
Frequently Asked Questions
Is the Fisher-Yates shuffle algorithm truly random?
The Fisher-Yates shuffle algorithm produces a uniform random permutation when every random selection is independent and uniformly distributed over its required range. In actual software, the output depends on the random number generator. A pseudorandom generator produces deterministic sequences from its internal state, so the practical quality of the shuffle depends on the generator as well as the algorithm.
Is Fisher-Yates better than sorting by random numbers?
Fisher-Yates is generally more efficient for shuffling an array because it runs in O(n) time and can operate in place. Sorting by random numbers typically requires O(n log n) time and extra storage. Fisher-Yates also avoids relying on random sort keys and the complications that can arise from ties.
Does Fisher-Yates guarantee equal-sized groups?
No. The algorithm rearranges participants but does not decide how many people belong in each group. Equal-sized groups require a separate grouping rule. For example, 24 participants can be divided into six groups of four after shuffling, while 25 participants cannot be divided into six exactly equal groups.
Can teachers use random shuffling to assign students to teams?
Yes. Teachers can shuffle a student list and divide the resulting sequence into teams of the desired size. This can reduce manual selection patterns and make assignments easier to organize. Teachers should still consider learning needs, accessibility, and any classroom rules that require particular students to work together or separately.
Does the algorithm change or remove any items?
No. Fisher-Yates changes the order of the original elements through swapping. Every item remains in the collection exactly once, assuming the implementation is correct. Duplicate values are also permitted, although identical values may make different underlying permutations appear visually identical.
Is Fisher-Yates suitable for large lists?
Yes. Its linear time complexity makes it suitable for large collections stored in random-access arrays. However, the random number generator, available memory, and implementation language can affect practical performance. Very large applications should also consider the limitations of their random number source.
Make Random Group Assignments Easier
The Fisher-Yates shuffle algorithm demonstrates how a small number of carefully controlled random decisions can create a fair permutation. Its shrinking selection range, simple swapping procedure, and linear-time performance make it an important concept in computer science and a useful foundation for random assignment systems.
For educators, trainers, and event organizers, the practical lesson is that fair randomization starts with a reliable process. You do not need to calculate random indices manually every time you organize an activity. You can prepare a participant list, choose the right grouping format, and use a dedicated tool to handle the assignment.
Try the Random Group Generator to organize participants into teams without manually rearranging every name. Whether you are preparing classroom activities, dividing workshop attendees, or planning collaborative workplace exercises, a consistent random grouping process can make preparation simpler and more transparent.
Related Tools
Pick the right generator for the job — every tool runs free in your browser.
