Concepts / Arrays and Index Positions

Arrays and Index Positions

Unsorting is the reverse goal of sorting: it aims for a random arrangement rather than an ordered one.

  • Programming

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?

  • It must stay the same size so every value stays available

  • It must grow so more values can be considered

  • It must shrink so settled values are never chosen again

Reveal answer
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

Definition

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.

Scan unfinishedpartScan unfinishedpartPick biggest itemPick random itemMove to end ofunfinished partMove to end ofunfinished partUnfinished partshrinksUnfinished partshrinks
The loop structure is identical in both columns. The only step that changes is how the item to settle is chosen: the biggest value in selection sort, a random item in the shuffle.

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.

Worked example

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.

  1. 1
    Pass 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.

  2. 2
    Pass 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.

  3. 3
    Pass 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.

  4. 4
    Pass 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].

Result

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.

index 04index 12index 23index 31
After pass one, which value sits at each index position, and which position is already settled? Index 3 is settled, and indexes 1 and 3 changed during this pass.

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 like

    On 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 fails

    A 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 instead

    Draw 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 fails

    If 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 instead

    Replace 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 fails

    If 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

MEDIUM

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.