Arrays and Index Positions
Unsorting is the reverse goal of sorting: it aims for a random arrangement rather than an ordered one.
Why Shuffle a Collection at All
Most of the sorting techniques you have studied start from a jumbled collection and produce an ordered one. This article turns that goal around. Instead of asking how to arrange values from smallest to largest, we ask how to arrange them so that the final order is unpredictable. The everyday picture is a deck of playing cards. Before a game, the cards are mixed so that no one can guess what comes next. That mixing is the problem this article solves, and it is the reverse of the problem sorting solves.
What do you think happens?
A shuffle repeatedly picks an item and moves it to the end of the unfinished part of the array. What must happen to the unfinished part after each pass for the shuffle to finish cleanly?
Reveal answer
It must shrink so settled values are never chosen again
Each pass settles one position at the end of the unfinished part. Once a value is settled, it is treated as finished and is not chosen again. Shrinking the range is what makes the shuffle terminate.
Sorting Versus Unsorting
Unsorting is the reverse goal of sorting: it aims for a random arrangement rather than an ordered one.
Unsorting is closely related to sorting. Both work on the same data structure, an array, and both rearrange its elements by moving them between index positions. The difference lies in what decides each move. A sorting algorithm uses the values themselves to decide where things belong. An unsorting algorithm uses chance to decide where things go. Keeping that difference in mind will help you understand every later step in this article.
The source material presents unsorting as a related problem that is less common than sorting but interesting to study in its own right. Because it uses the same kind of array and the same kind of step-by-step movement that sorting uses, it is a good way to check whether you understand how those movements work.
Borrowing Selection Sort's Skeleton
A good shuffling algorithm is built on the same skeleton as selection sort. Recall how selection sort works: it repeatedly looks through the part of the array that is not yet finished, finds the biggest item, and moves that item to the end of the unfinished part. Each pass fixes one more position at the end, and the unfinished part shrinks until nothing is left.
The shuffle keeps this skeleton and changes exactly one decision. Where selection sort chooses the biggest item, the shuffle chooses an item at random. The chosen item is then moved to the end of the unfinished part, just as selection sort moves its biggest item. Because the structure is the same, every pass still settles one position and the work still shrinks from one pass to the next. Only the choice of which item to settle has changed.
Tracing a Shuffle by Hand
The best way to see how the shuffle works is to step through a small array. The values below are invented for this walkthrough, and the random choices are chosen by hand to show the mechanics. In a real shuffle, the choice at each pass would come from a random source. Start with the array [4, 1, 3, 2] at index positions 0 through 3. Every position is unfinished at the start.
Shuffling [4, 1, 3, 2] by hand
Shuffle the array [4, 1, 3, 2]. On each pass, choose one item from the unfinished part at random, then move it to the end of the unfinished part. Assume the random choices in this example are 1, then 0, then 0.
- 1Pass one: unfinished part is indexes 0 to 3
The random choice is index 1, which holds the value 1. Move it to the end of the unfinished part, index 3, by swapping it with the value 2 there. The array becomes [4, 2, 3, 1]. Index 3 is now settled.
- 2Pass two: unfinished part is indexes 0 to 2
Index 3 is settled and must not be chosen again. The random choice is index 0, which holds the value 4. Move it to the end of the unfinished part, index 2, by swapping it with the value 3. The array becomes [3, 2, 4, 1]. Indexes 2 and 3 are now settled.
- 3Pass three: unfinished part is indexes 0 to 1
The random choice is index 0, which holds the value 3. Move it to the end of the unfinished part, index 1, by swapping it with the value 2. The array becomes [2, 3, 4, 1]. Indexes 1, 2, and 3 are now settled.
- 4Pass four: unfinished part is index 0 only
Only index 0 remains. The only choice is index 0 itself, so nothing moves. The final arrangement is [2, 3, 4, 1].
The shuffled array is [2, 3, 4, 1]. Each pass settled exactly one position, and the unfinished part shrank from four positions to one.
The index view below shows the state after pass one. Each position is listed with the value it holds, so you can see exactly which values moved. Index 1 changed from 1 to 2, and index 3 changed from 2 to 1. Index 3 is the settled position, because the value there has been moved to the end of the unfinished part.
Why the Unfinished Part Must Shrink
Notice that the unfinished part gets smaller after each pass, and this is what makes the shuffle terminate. Once a value has been moved to the end of the unfinished part, it is treated as settled and is not chosen again. If the algorithm kept choosing from the whole array, a value could be picked repeatedly, and the work would never clearly finish. Shrinking the range is therefore part of the design, not an optional detail.
Mistakes in Shuffle Design
The source material identifies two broad sources of error in shuffle design. Mistakes usually come from choosing from settled values or from keeping the sorting rule unchanged. The items below describe each error and how to avoid it.
Common mistake Choosing from the whole array on every pass
What it looks likeOn pass two of the trace, the random choice is drawn from indexes 0 to 3, so index 3, which is already settled, can be picked again.
Why it failsA settled value is moved again, and the work never clearly finishes. The number of passes is no longer tied to the size of the array.
Do this insteadDraw each random choice only from the unfinished part. On pass two, that is indexes 0 to 2.
Common mistake Keeping the biggest-item rule from selection sort
Why it failsIf the algorithm still picks the biggest item, the result is an ordered arrangement, which is the opposite of the goal. The rule that decides the move was never changed.
Do this insteadReplace the choice of the biggest item with a random choice. Keep the rest of the loop the same: scan the unfinished part, choose, move to the end, and shrink.
Common mistake Forgetting that the unfinished part must shrink
Why it failsIf the unfinished part stays the same size, the algorithm has no clear measure of progress, and settled positions are not protected.
Practice: Trace Your Own Shuffle
Shuffle the array [5, 2, 8, 1] by hand. On each pass, choose an index from the unfinished part only, then move the chosen value to the end of the unfinished part by swapping. Use these random choices in order: index 2, then index 0, then index 1. Write the array after each pass and state which positions are settled.
Hints
- Pass one's unfinished part is indexes 0 to 3, so the first choice of index 2 holds the value 8. Swap it with the value at index 3.
- After each pass, the last settled position moves one step to the left. Check that you never choose an index that is already settled.
- Pass four needs no swap, because only one unfinished position remains.
Key Takeaways
- Unsorting aims for a random arrangement, while sorting aims for an ordered one. Sorting uses the values to decide where things belong, and unsorting uses chance.
- A shuffle reuses selection sort's skeleton: scan the unfinished part, choose an item, move it to the end of the unfinished part, and shrink. Only the choice changes, from the biggest item to a random item.
- Each pass settles one index position, so the unfinished part must shrink after every pass. Settled values must never be chosen again.
- Common shuffle errors come from choosing from settled values or from keeping the selection sort rule unchanged. Keep choices limited to the unfinished part and replace the biggest-item rule with a random one.