Defining Algorithms
An algorithm is simply a step-by-step procedure for solving a problem or accomplishing a task. It's a precise set of instructions that, when followed correctly, produces a desired result. Algorithms aren't unique to computers—you use them every day without realizing it.
Think of a recipe for baking cookies: mix ingredients in a specific order, bake at a certain temperature, cool for a set time. That's an algorithm. In programming, algorithms solve computational problems using the same principle: clear, unambiguous steps.
Everyday Algorithm Examples
Before diving into code, let's look at algorithms in daily life:
- Making coffee: Boil water → Add coffee grounds to filter → Pour water over grounds → Wait for brewing → Pour into cup
- Finding a word in dictionary: Open to middle → Is word before or after? → Repeat with appropriate half → Found word
- Getting dressed: Put on underwear → Put on pants → Put on shirt → Put on socks → Put on shoes
Notice how each algorithm has a clear start, specific steps, and a defined end goal. Computer algorithms work the same way.
Algorithm Characteristics
A good algorithm must have these properties:
- Input: Takes zero or more inputs
- Output: Produces at least one output
- Definiteness: Each step is clear and unambiguous
- Finiteness: Terminates after a finite number of steps
- Effectiveness: Steps are basic enough to be executed
Pseudocode: Planning Before Coding
Pseudocode helps design algorithms before writing real code:
// Algorithm: Find maximum number in a list
FUNCTION findMaximum(numbers):
SET max to first number in list
FOR EACH number in numbers:
IF number > max:
SET max to number
RETURN max
// Example usage
numbers = [5, 2, 9, 1, 7]
maximum = findMaximum(numbers) // Returns 9
Real Programming Example
Here's the same algorithm in JavaScript:
function findMaximum(numbers) {
let max = numbers[0];
for (let i = 1; i < numbers.length; i++) {
if (numbers[i] > max) {
max = numbers[i];
}
}
return max;
}
// Test the algorithm
const numbers = [5, 2, 9, 1, 7];
const maximum = findMaximum(numbers);
console.log(maximum); // Output: 9
Big O Notation Basics
Big O describes how an algorithm's runtime grows as input size increases:
- O(1) - Constant: Same time regardless of input size (accessing array element)
- O(log n) - Logarithmic: Time grows slowly (binary search)
- O(n) - Linear: Time grows proportionally to input (finding max in list)
- O(n²) - Quadratic: Time grows with square of input (nested loops)
- O(2ⁿ) - Exponential: Time doubles with each addition (some recursive algorithms)
Example comparison with 1000 items:
- O(1): 1 operation
- O(log n): ~10 operations
- O(n): 1,000 operations
- O(n²): 1,000,000 operations
Common Sorting Algorithms
Sorting is a fundamental algorithmic problem. Here's bubble sort, one of the simplest:
function bubbleSort(arr) {
const n = arr.length;
// Outer loop: number of passes
for (let i = 0; i < n - 1; i++) {
// Inner loop: compare adjacent elements
for (let j = 0; j < n - i - 1; j++) {
// Swap if elements are in wrong order
if (arr[j] > arr[j + 1]) {
const temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
// Test
const unsorted = [64, 34, 25, 12, 22, 11, 90];
const sorted = bubbleSort(unsorted);
console.log(sorted); // [11, 12, 22, 25, 34, 64, 90]
Bubble sort has O(n²) complexity—it's simple but inefficient for large datasets. More advanced algorithms like quicksort and mergesort are faster (O(n log n)).
Search Algorithms
Linear search checks each element sequentially:
function linearSearch(arr, target) {
for (let i = 0; i < arr.length; i++) {
if (arr[i] === target) {
return i; // Found at index i
}
}
return -1; // Not found
}
// O(n) complexity - checks each element once
Binary search is faster but requires a sorted array:
function binarySearch(arr, target) {
let left = 0;
let right = arr.length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (arr[mid] === target) {
return mid; // Found
} else if (arr[mid] < target) {
left = mid + 1; // Search right half
} else {
right = mid - 1; // Search left half
}
}
return -1; // Not found
}
// O(log n) complexity - eliminates half the data each step
Algorithm Design Strategies
- Brute Force: Try all possibilities (simple but often slow)
- Divide and Conquer: Break problem into smaller subproblems (binary search, mergesort)
- Greedy: Make locally optimal choice at each step (coin change)
- Dynamic Programming: Store results of subproblems to avoid recalculation (Fibonacci)
- Backtracking: Try solutions, undo if they don't work (sudoku solver)
Why Algorithms Matter
Understanding algorithms helps you:
- Write more efficient code that runs faster and uses less memory
- Choose the right approach for solving problems
- Pass technical interviews at major tech companies
- Understand how existing tools and libraries work
- Optimize database queries and API calls
- Debug performance issues in applications
Practice Resources
Improve your algorithm skills:
- LeetCode: Thousands of algorithm problems with solutions
- HackerRank: Algorithm challenges organized by difficulty
- Project Euler: Mathematical/computational problems
- Codewars: Gamified coding challenges
- AlgoExpert: Video explanations of common interview algorithms
Next Steps
Continue learning about:
- Data structures (arrays, linked lists, trees, graphs)
- Recursion and recursive algorithms
- Graph algorithms (BFS, DFS, Dijkstra)
- String manipulation algorithms
- Algorithm analysis and proof techniques
Algorithms are the heart of computer science. Master them, and you'll become a significantly better programmer!




