An algorithm is a recipe: a list of steps so precise that someone who doesn't understand the goal at all could still follow it and get the right answer. Computers are exactly that kind of "someone". This page shows what makes a recipe precise enough, then puts two classic recipes for sorting side by side so you can watch them work, count their effort, and see why some algorithms are much faster than others.

A recipe with no room for guessing

Imagine telling a friend "put these cards in order". They'll manage, because they fill in the gaps: smallest first? by suit? They just know. A computer fills in nothing. It does exactly what each step says, one step at a time, and nothing else. So an algorithm needs three things:

Too vague

  1. Look at the numbers.
  2. Move the small ones towards the front.
  3. Stop when it looks right.

Precise

  1. Compare item 1 with item 2. If the left one is bigger, swap them.
  2. Do the same for items 2 and 3, then 3 and 4… to the end.
  3. If you swapped anything, go back to step 1. If not, stop.

"Small ones", "towards" and "looks right" all need a human to interpret them. The right-hand version uses only two actions a computer can do directly: a comparison (is this number bigger than that one?) and a swap (exchange two items' places). That right-hand recipe is a real, famous algorithm. It's called bubble sort.

Why sorting?

Sorting means putting items in order: numbers smallest to largest, names A to Z, emails newest first. Your music app, your bank statement and every search results page sort things constantly. It's also the classic way to learn about algorithms, because there are dozens of different recipes that all produce the same correct answer, yet take wildly different amounts of work to get there. That's the big idea: an algorithm isn't just "does it work?" but also "how much effort does it take?"

We'll measure effort the simplest honest way: count the comparisons and the swaps. Those are the steps that do the actual work.

Two recipes for the same job

Bubble sort

Walk along the row comparing neighbours. Whenever the left one is bigger, swap them. After one full walk (a pass), the biggest number has been carried all the way to the right end, like a bubble rising to the top. It's now in its final place, so the next pass can stop one item earlier. Keep making passes; when a whole pass makes no swaps, everything is in order and you stop.

Selection sort

Scan the whole unsorted part of the row and remember where the smallest number is. When you reach the end, swap that smallest number into the first unsorted spot. That spot is now done. Repeat for the rest of the row. Selection sort makes lots of comparisons but very few swaps: at most one per pass.

Same input, same goal, different recipes. Step through them and watch the counters.

Sort visualizer

start:
comparingswappedsmallest so farin final place
0comparisons
0swaps
0step

On the starting row 5 2 7 1 6 3, bubble sort needs 14 comparisons and 8 swaps; selection sort needs 15 comparisons but only 2 swaps. Now try the other starting orders:

Neither one "wins" everywhere. If swapping is expensive (say, moving heavy boxes in a warehouse), selection sort's few swaps are attractive. If the data is often nearly sorted already, bubble sort's early stop helps. Picking an algorithm means knowing what your input usually looks like.

Be the computer

Here's a fresh row of numbers and the bubble sort recipe. You do the work: for each highlighted pair, decide whether a computer following the recipe would swap them. The rule is just one comparison, is the left number bigger than the right?, but notice how many times you have to make it.

Bubble sort, by hand

Tedious, right? That's the point. A computer does exactly this, but billions of times a second and without ever getting bored or sloppy. The recipe never needs to know what the numbers mean, only how to compare two of them.

Why some algorithms are faster

Let's count the worst case. With n items, bubble sort's first pass makes n − 1 comparisons, the next n − 2, and so on down to 1. Add those up and you get n × (n − 1) ÷ 2. Selection sort makes exactly that many comparisons every time. For 6 items that's 15, which matches the counters above.

That formula has an n × n hiding inside it, and that's the problem. Double the number of items and the work roughly quadruples. Programmers call this quadratic growth and write it as O(n²) (said "big O of n squared"), a shorthand for "grows like n times n".

Cleverer algorithms such as merge sort split the row in half, sort each half, then merge the two sorted halves back together. That trick brings the worst case down to roughly n × log₂ n comparisons, written O(n log n). log₂ n is "how many times can you halve n before reaching 1", which grows very slowly: about 10 for a thousand, about 20 for a million. Drag the slider to see what that difference means.

How the work grows

number of items (n)10
bubble / selection ≈ n(n−1)/2
merge sort ≈ n·log₂n

For a handful of items, nobody can tell the difference, and simple algorithms are perfectly fine. For a million items the simple ones need about 500 billion comparisons while merge sort needs about 20 million. Same answer, roughly 25,000 times less work. That's why "how does the effort grow as the input grows?" is the first question programmers ask about any algorithm, and it matters more than buying a faster computer.

The same thing in JavaScript

Here are both recipes as real JavaScript functions. Each one takes a list (an array), sorts a copy of it, and also counts its comparisons and swaps so you can check the numbers from the visualizer. You can paste this into your browser's developer console or save it as sort.js and run node sort.js.

function bubbleSort(list) {
  const a = [...list];            // work on a copy
  let comparisons = 0, swaps = 0;
  for (let end = a.length - 1; end > 0; end--) {
    let swapped = false;
    for (let i = 0; i < end; i++) {
      comparisons++;
      if (a[i] > a[i + 1]) {
        [a[i], a[i + 1]] = [a[i + 1], a[i]];   // swap the pair
        swaps++;
        swapped = true;
      }
    }
    if (!swapped) break;          // a pass with no swaps: done
  }
  return { sorted: a, comparisons, swaps };
}

function selectionSort(list) {
  const a = [...list];
  let comparisons = 0, swaps = 0;
  for (let start = 0; start < a.length - 1; start++) {
    let min = start;              // smallest seen so far
    for (let i = start + 1; i < a.length; i++) {
      comparisons++;
      if (a[i] < a[min]) min = i;
    }
    if (min !== start) {
      [a[start], a[min]] = [a[min], a[start]];
      swaps++;
    }
  }
  return { sorted: a, comparisons, swaps };
}

const bars = [5, 2, 7, 1, 6, 3];
console.log(bubbleSort(bars));
console.log(selectionSort(bars));

Running it with node sort.js prints:

{ sorted: [ 1, 2, 3, 5, 6, 7 ], comparisons: 14, swaps: 8 }
{ sorted: [ 1, 2, 3, 5, 6, 7 ], comparisons: 15, swaps: 2 }

A few pieces of syntax worth knowing:

In real code you'd just call JavaScript's built-in sort, which uses a much faster algorithm than either of these. One beginner trap: by default it sorts items as text, so [10, 9, 1].sort() gives [ 1, 10, 9 ] ("10" comes before "9" alphabetically). For numbers, pass a comparison: [10, 9, 1].sort((a, b) => a - b) gives [ 1, 9, 10 ].

Check yourself

Which instruction is too vague to be a step in an algorithm?

"Big" and "roughly" need human judgement. The other two say exactly what to compare and what to do, so a computer can carry them out without guessing.

Bubble sort (with the "stop if no swaps" rule) on [3, 1, 2]. How many swaps?

Pass 1: 3 > 1, swap → [1, 3, 2]; 3 > 2, swap → [1, 2, 3]. Pass 2: 1 > 2? No. No swaps, so it stops. Two swaps, three comparisons.

Selection sort on 6 numbers that are already sorted. How many comparisons?

Selection sort has no early exit. It always scans the rest of the row to find the smallest: 5 + 4 + 3 + 2 + 1 = 15. (Bubble sort would stop after 5.)

An O(n²) algorithm takes 1 second for 1,000 items. Roughly how long for 2,000?

Quadratic means the work grows like n × n. Double n and the work is 2 × 2 = 4 times bigger.

The short version

Next time an app sorts a long list in a blink, you'll know there's a carefully chosen recipe behind it, not just a fast machine.