Skip to content
BytePatterns

Cyclic Sort

Arrays: lesson 9 of 14

When values are 1..n, every value already knows its index.

Lesson 9 of 14 · 5 min

Cyclic Sort

Step 1 of 6

Values 1..n in some order, so every value already knows its slot: v belongs at index v − 1.

The Idea

When an array holds the numbers 1 to n in some order, each value already knows where it belongs: value v goes to index v-1. So walk the array, and whenever the value under the cursor is not home, swap it straight there. Keep swapping until the current slot is settled, then step forward. Every swap parks one value permanently, so the whole thing is one linear pass — and it finds missing or duplicated numbers for free.

Real-World Example

A cloakroom hands out tickets 1 to n. At closing time the attendant does not sort the rail. He lifts the coat in front of him, hangs it on the peg its ticket names, and picks up whatever was hanging there. Each walk finishes one coat.

The Code

def cyclic_sort(nums):
    i = 0
    while i < len(nums):
        home = nums[i] - 1          # value v belongs at index v-1
        if nums[i] != nums[home]:   # not home yet -> send it there
            nums[i], nums[home] = nums[home], nums[i]
        else:
            i += 1                  # settled, move the cursor on
    return nums

print(cyclic_sort([3, 1, 5, 4, 2]))   # [1, 2, 3, 4, 5]

Python

Your turn

What does this print?

nums = [2, 1, 3]
i = swaps = 0
while i < len(nums):
  h = nums[i] - 1
  if nums[i] != nums[h]:
      nums[i], nums[h] = nums[h], nums[i]
      swaps += 1
  else:
      i += 1
print(swaps)

Mini quiz

1 / 3

Why does cyclic sort need values in the range 1..n?

New lessons land every few weeks

Leave an address and we will tell you when the next one is up. That is the only reason we will use it.

One address, stored so we can email you. Nothing else, ever.