Before a single line of code is written, every good program starts as a plan — a precise sequence of steps for solving a problem. That plan is an algorithm, and learning to build one is the real skill behind programming.
An algorithm is a precise, ordered set of steps for solving a specific problem — nothing more mystical than that. GPS directions, a search engine ranking results, a recipe, and a sorting feature in a spreadsheet are all algorithms. Code is simply how an algorithm gets expressed in a language a computer can run. This guide is about the thinking that happens before the code — the skill of designing the steps in the first place.
Not every set of instructions qualifies as an algorithm. To count, a sequence of steps generally needs three properties: it must be well-defined (each step is unambiguous, with nothing left to guesswork), it must be finite (it eventually stops, rather than running forever), and it must produce a correct output for the problem it claims to solve. A recipe that says "cook until it feels right" isn't a strict algorithm; a recipe that says "bake at 180°C for 25 minutes" is.
The same problem can usually be solved by more than one algorithm. Looking up a word in a printed dictionary by starting at page one and reading every page is a valid algorithm — it would eventually find the word. Opening to roughly the middle, checking which half the word falls in, and repeating is a different, far faster algorithm for the exact same problem. Algorithm design is largely about finding the second kind of solution instead of the first.
Experienced programmers rarely jump straight into a programming language. They first sketch the logic using tools that aren't tied to any specific language's syntax, so they can focus purely on the steps and decisions involved.
A flowchart represents an algorithm visually — ovals for start/end points, rectangles for actions, and diamonds for decisions that branch the path depending on a condition.
Pseudocode is the text equivalent — plain, structured writing that looks similar to real code but isn't tied to any language's exact rules, making it easier to plan logic before worrying about syntax.
START ASK the user for a number IF number is divisible by 2 THEN PRINT "Even" ELSE PRINT "Odd" END IF END
Searching for an item in a collection is one of the most common problems in computing, and it has two classic solutions with very different performance.
Linear search checks each item one at a time, in order, until it finds a match or reaches the end.
def linear_search(numbers, target): for i in range(len(numbers)): if numbers[i] == target: return i return -1
Binary search only works on sorted data, but is dramatically faster: it checks the middle item, and — because the data is sorted — instantly eliminates half the remaining possibilities depending on whether the target is higher or lower, repeating this until it's found.
def binary_search(sorted_numbers, target): low, high = 0, len(sorted_numbers) - 1 while low <= high: mid = (low + high) // 2 if sorted_numbers[mid] == target: return mid elif sorted_numbers[mid] < target: low = mid + 1 else: high = mid - 1 return -1
| Feature | Linear Search | Binary Search |
|---|---|---|
| Requires sorted data | No | Yes |
| Worst case, 1,000 items | Up to 1,000 checks | About 10 checks |
| Best for | Small or unsorted collections | Large, sorted collections |
Sorting is another classic problem: arranging data into order. Bubble sort is one of the simplest sorting algorithms to understand — it repeatedly compares neighbouring items and swaps them if they're in the wrong order, gradually "bubbling" the largest values to the end.
def bubble_sort(numbers): n = len(numbers) for i in range(n): for j in range(n - i - 1): if numbers[j] > numbers[j + 1]: numbers[j], numbers[j + 1] = numbers[j + 1], numbers[j] return numbers
Bubble sort is easy to understand but slow on large data, because it may compare and re-compare nearly every pair of items. Algorithms like merge sort and quicksort solve the same problem far more efficiently by repeatedly splitting the data into smaller pieces, sorting those, and combining the results — the same "divide and conquer" instinct behind binary search. This is exactly why the earlier article on coding introduced Big O notation: two algorithms can produce an identical correct result while behaving completely differently as the amount of data grows.
Recursion is a technique where a function solves a problem by calling a smaller version of itself, until it reaches a simple case it can answer directly, called the base case. It's a natural fit for problems that are naturally defined in terms of smaller versions of themselves.
def factorial(n): if n == 0: # base case return 1 return n * factorial(n - 1) print(factorial(4))
Every recursive function needs a base case — without one, it would call itself forever and eventually crash the program. Recursion often produces shorter, more elegant code for tree-like or nested problems, though the same logic can usually also be written using a loop.
Algorithms aren't just an academic exercise — they quietly run enormous parts of daily life. Beyond search and sort, algorithms decide GPS routes by comparing thousands of possible paths, rank social media posts and search results, detect fraudulent card transactions in real time, and power the recommendation lists behind streaming and shopping sites.
When a map app calculates a driving route, it's running a pathfinding algorithm (a well-known one is called Dijkstra's algorithm) that treats roads as a giant network and finds the shortest or fastest path through it — comparing an enormous number of possible routes in a fraction of a second rather than checking every possible path by brute force.
Code is the language an algorithm ends up expressed in — but the algorithm itself, the actual thinking, happens beforehand. Every experienced programmer spends more mental effort planning the steps than typing the syntax. Practising algorithmic thinking — breaking a problem into well-defined, ordered steps, and asking whether a smarter approach exists — is a skill that keeps paying off no matter which programming language you eventually use it in.
10 questions. Select an answer for each, then submit to see your score instantly.