Big O Notation
Computational Complexity
Algorithm Analysis
Asymptotic Analysis
Mathematical Proofs

n log n is On?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Understanding algorithmic complexity is crucial for computer science and software development, especially when it comes to sorting operations, data structures, and other performance-critical tasks. Within this context, it's common to encounter complexity expressions like nlognn \log n and O(n)O(n). This article will delve into why nlognn \log n is considered O(n2)O(n^2) but not O(n)O(n), exploring its meaning, implications, and applications.

Asymptotic Notation

Asymptotic notation provides a way to describe the efficiency and performance of an algorithm in terms of its time or space complexity, particularly as the input size grows indefinitely. The three most frequently used asymptotic notations are:

  • Big O (OO-notation): Provides an upper bound on the time complexity, indicating the worst-case scenario.
  • Big Omega (Ω\Omega-notation): Offers a lower bound, showing the best-case scenario.
  • Big Theta (Θ\Theta-notation): Describes a tight bound, representing the average or expected scenario.

Big O Notation: O(n)O(n)

Big O notation, O(f(n))O(f(n)), provides an upper bound for the growth rate of a function. If T(n)T(n) is the time complexity of an algorithm, then T(n)T(n) is O(f(n))O(f(n)) if there exist constants c>0c > 0 and n00n_0 \geq 0 such that for all nn0n \geq n_0, T(n)cf(n)T(n) \leq c \cdot f(n).

Understanding nlognn \log n

The term nlognn \log n is frequently encountered in algorithms such as Merge Sort, Quick Sort, and Heap Sort, which have average-case time complexities of O(nlogn)O(n \log n). Here, the function logn\log n often refers to log2n\log_2 n, the binary logarithm, which is common in computer science contexts where binary data is processed.

Why nlognn \log n is Not O(n)O(n)

To understand why nlognn \log n is not O(n)O(n), consider the relationship between these two functions:

  1. Growth Rate: The growth rate of nlognn \log n is faster than nn for large values of nn. While logn\log n grows very slowly compared to linear or polynomial functions, when multiplied by nn, the combined function nlognn \log n grows more quickly than nn.
  2. Proof by Contradiction: Let's attempt to prove that nlognn \log n is O(n)O(n). It implies there exist constants c>0c > 0 and n00n_0 \geq 0 such that for all nn0n \geq n_0, nlogncnn \log n \leq c \cdot n. Simplifying, we get lognc\log n \leq c. Since logn\log n grows indefinitely as nn increases, no such constant cc can exist, thus proving nlognn \log n is not O(n)O(n).

n log n in the Hierarchy of Functions

To visualize this, consider the following hierarchy of growth rates:

  • Constant: O(1)O(1)
  • Logarithmic: O(logn)O(\log n)
  • Linear: O(n)O(n)
  • Linearithmic: O(nlogn)O(n \log n)
  • Quadratic: O(n2)O(n^2)
  • Cubic: O(n3)O(n^3)
  • Exponential: O(2n)O(2^n)

Practical Example

Consider a Merge Sort algorithm, which efficiently sorts an array of nn elements. The algorithm divides the array in half, sorts each half recursively, and then merges the sorted halves. This divide-and-conquer approach has a time complexity of O(nlogn)O(n \log n). While it is significantly better than O(n2)O(n^2) algorithms like Bubble Sort for large nn, it is still not as efficient as linear time algorithms like Counting Sort, which are feasible when certain conditions are met.

Summary Table

FunctionDescriptionGrowth Relative to nn
O(1)O(1)Constant timeSame
O(logn)O(\log n)Logarithmic timeSlower
O(n)O(n)Linear timeBaseline
O(nlogn)O(n \log n)Linearithmic timeFaster
O(n2)O(n^2)Quadratic timeMuch Faster

Conclusion

While nlognn \log n often appears in algorithm analysis as a desirable and efficient time complexity, particularly in sorting and other divide-and-conquer algorithms, it is strictly not O(n)O(n). Understanding these distinctions allows developers to make informed choices about algorithm selection and performance optimization. Recognizing that nlognn \log n grows more rapidly than linear time but less so than quadratic time helps calibrate expectations about algorithm performance, especially with large data sets.


Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.