Big O Notation and Other Alternatives
Article Image
Article Image
read

Big-O is more than a notation. It is the universal score sheet where algorithms reveal their rhythm in the face of infinity.
If Θ sets the tempo and Ω marks the bass line, O describes the dramatic crescendo of the worst case.

Introduction

In computer science, asymptotic analysis is the shared language that allows us to compare algorithms fairly.
Some grow like flickering meteors, vanishing in exponential time, while others shine steadily across the sky, sustained by polynomial growth.

This post revisits Big-O, introduces Ω and Θ with mathematical precision, and walks through concrete examples — from
\(T(n) = 10n^2 + 137n + 15\)
to the classical ArrayMax algorithm and Horner’s method for polynomial evaluation.

Formal Definitions

Let $f(n)$ and $g(n)$ be functions from $\mathbb{N}$ to $\mathbb{R}^+$.

  • Big-O (upper bound):
    \(f(n) \in O(g(n)) \iff \exists c>0, n_0>0 : \forall n \geq n_0, f(n) \leq c \cdot g(n)\)

  • Big-Omega (lower bound):
    \(f(n) \in \Omega(g(n)) \iff \exists c>0, n_0>0 : \forall n \geq n_0, f(n) \geq c \cdot g(n)\)

  • Big-Theta (tight bound):
    \(f(n) \in \Theta(g(n)) \iff f(n) \in O(g(n)) \wedge f(n) \in \Omega(g(n))\)

  • Little-o (strictly smaller growth):
    \(f(n) \in o(g(n)) \iff \forall c>0, \exists n_0 : \forall n \geq n_0, f(n) < c \cdot g(n)\)

  • Little-omega (strictly larger growth):
    \(f(n) \in \omega(g(n)) \iff \forall c>0, \exists n_0 : \forall n \geq n_0, f(n) > c \cdot g(n)\)

These definitions formalize the intuition: constants and lower-order terms fade into irrelevance, and only the dominant term survives the infinity test.

Worked Example 1: The Quadratic Dominator

Consider \(T(n) = 10n^2 + 137n + 15.\)

  • For $n = 10$: $T(10) = 12{,}585$, where the quadratic term is still modest.
  • For $n = 1000$: $T(1000) \approx 10^7$, with the quadratic term accounting for more than 99% of the value.

Formally: \(T(n) \in \Theta(n^2).\)

The lower terms are like supporting instruments in an orchestra: present, but eventually drowned by the booming percussion of $n^2$.

Worked Example 2: ArrayMax (Operation Count)

From Alonso’s classic material, the algorithm to find the maximum element in an array of size $n$ is:

int arrayMax(int A[], int n) {
    int currentMax = A[0];
    for (int i=1; i<n; i++) {
        if (A[i] > currentMax)
            currentMax = A[i];
    }
    return currentMax;
}

Counting primitive operations yields: \(T(n) = 6n - 1.\)

This is linear, so \(T(n) \in \Theta(n).\)

Doubling the input size doubles the runtime. Linearity is the algorithm’s fingerprint.

Worked Example 3: Horner’s Method vs. Classical Evaluation

Evaluating a polynomial conventionally requires:

  • $n$ additions
  • $\frac{n(n+1)}{2}$ multiplications

Horner’s method rewrites \(p(x) = a_nx^n + a_{n-1}x^{n-1} + \dots + a_1x + a_0\) as \(p(x) = a_0 + x(a_1 + x(a_2 + \dots + x(a_n)\dots))\)

requiring only:

  • $n$ additions
  • $n$ multiplications

In Python:

def horner(coeffs, x):
    result = 0
    for a in reversed(coeffs):
        result = result * x + a
    return result

The complexity is $\Theta(n)$, a dramatic improvement over the quadratic classical method.

Mini-Proof with Induction

Induction pairs beautifully with asymptotics. Consider:

Claim: $2^n < n!$ for all $n > 3$.

  • Base case: $n=4$, $2^4 = 16 < 24 = 4!$.
  • Inductive step: Assume $2^n < n!$. Then \(2^{n+1} = 2 \cdot 2^n < 2 \cdot n! < (n+1)!,\) because $n+1 > 2$ for $n > 3$.

Thus the inequality holds for all $n > 3$.

This shows factorial growth outpaces exponentials, anchoring why algorithms like brute-force permutations are catastrophic in practice.

Reflection: Why This Matters

Big-O, Θ, and Ω are not merely theoretical ornaments. They are survival maps for software engineers navigating the unknown territories of scale.
When millions of transactions, requests, or data points arrive, these notations predict whether our systems endure or collapse.

Beyond the Notation

Mathematical notation is often mistaken for abstraction. But in truth, it is poetry — compressed, symbolic, universal.
Big-O is not the cage of an algorithm; it is its cosmic signature. Knowing whether a function grows linearly or quadratically is like knowing whether a star burns for billions of years or collapses in a brief supernova.

The study of growth rates opens the door to recursion, sorting, and graph algorithms. Step by step, we move from rhythm to harmony, from single melodies to symphonies of complexity.

Exercises

  1. Prove that $n^2 + 10n + 100 \in \Theta(n^2)$.
  2. Show by induction that the binary representation of $n$ requires $\lfloor \log_2 n \rfloor + 1$ bits.
  3. Compare the number of operations required to evaluate $p(x) = x^5 + x^4 + x^3 + x^2 + x + 1$ conventionally and with Horner’s method.
  4. Suppose an algorithm has runtime $T(n) = 5n \log n + 20n$. Show that $T(n) \in \Theta(n \log n)$.

References

Blog Logo

Richardson Lima


Published

Image

Richardson Lima

A brain dump about technology and some restrict interests.

Back to Overview