Fisher-Yates Shuffle
The definitive guide to unbiased array randomization
What is the Fisher-Yates Shuffle?
The Fisher-Yates shuffle (also known as the Knuth shuffle) is an algorithm for generating a random permutation of a finite sequence—in plain terms, for randomly shuffling an array. It produces an unbiased permutation: every permutation is equally likely.
Historical Context
The algorithm was first described by Ronald Fisher and Frank Yates in 1938 in their book Statistical Tables for Biological, Agricultural and Medical Research. Later, Donald Knuth popularized it in The Art of Computer Programming.
Why It Matters
Many naive shuffling algorithms produce biased results. Fisher-Yates is efficient (O(n) time complexity) and mathematically proven to be unbiased, making it the gold standard for shuffling.
How It Works
The Algorithm Steps
- Start with the last element in the array (index n-1)
- Pick a random index between 0 and the current index (inclusive)
- Swap the element at the current index with the element at the random index
- Move to the previous element (decrement index by 1)
- Repeat until you reach the first element
Pseudocode
// Fisher-Yates Shuffle Pseudocode
for i from n−1 downto 1 do
j ← random integer such that 0 ≤ j ≤ i
exchange a[j] and a[i]
Visual Demonstration
Implementation Examples
Modern ES6 Implementation
/**
* Fisher-Yates Shuffle (ES6 implementation)
* @param {Array} array - The array to shuffle
* @returns {Array} The shuffled array (mutates original)
*/
function fisherYatesShuffle(array) {
// Loop from last element to first
for (let i = array.length - 1; i > 0; i--) {
// Random index from 0 to i (inclusive)
const j = Math.floor(Math.random() * (i + 1));
// ES6 destructuring swap
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
Hover to see explanation
Key Features
- Uses ES6 array destructuring for clean swapping
- Works in-place (modifies original array)
- Returns the shuffled array for chaining
- Time complexity: O(n)
- Space complexity: O(1)
Traditional Implementation
/**
* Fisher-Yates Shuffle (Traditional implementation)
* @param {Array} array - The array to shuffle
* @returns {Array} The shuffled array (mutates original)
*/
function fisherYatesShuffle(array) {
var currentIndex = array.length,
temporaryValue,
randomIndex;
// While there remain elements to shuffle...
while (currentIndex !== 0) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
Hover to see explanation
Key Features
- Uses temporary variable for swapping
- More verbose but works in all JavaScript versions
- Same time and space complexity as ES6 version
- Easier to debug with separate steps
Common Mistakes and Pitfalls
Naive Shuffling (Incorrect)
// ⚠️ Warning: This produces biased results!
// The sort comparator function doesn't guarantee uniform distribution
array.sort(() => Math.random() - 0.5);
This approach seems simple but produces non-uniform distributions because the sorting algorithm's comparison mechanism isn't designed for randomness.
Off-by-One Errors
// ⚠️ Common mistake - j should be ≤ i, not < i
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * i); // Wrong!
[array[i], array[j]] = [array[j], array[i]];
}
This excludes the possibility of an element swapping with itself, which is mathematically necessary for uniform distribution.
Applications of Fisher-Yates Shuffle
Card Games
Shuffling decks of cards in digital card games where fair distribution is critical.
Random Sampling
Selecting random subsets from larger datasets in statistical analysis.
Music Players
Creating truly random playlists where each song has equal chance of playing next.
Machine Learning
Randomizing training data batches to prevent order-based biases.
A/B Testing
Randomly assigning users to test groups in web experiments.
Cryptography
Generating random permutations for cryptographic applications.
Interactive Shuffle Tester
Test the Algorithm
Enter items (comma separated) to create an array and see the Fisher-Yates shuffle in action.
Distribution Results
Shuffle the array multiple times to see the distribution of results.
Current Array
Shuffle Steps
Shuffle steps will appear here...