Sorting algorithms

The goals of this "project" include a) familiarizing myself with a few sorting algorithms by examining their (possibly, simplified) implementations and b) studying the way algorithm's running time changes in relation to the length of its input (a.k.a. identifying its time complexity).

A simple way to visualize the way algorithm's running time changes is to make appropriate measurements and plot them on a nice graph. The results of course are highly dependent on the hardware used, while the graph's look depends on the software used for rendering.

Both the hardware & the software that were used to produce the plots are listed below.

CPU Intel Core i7-7500U
OS Linux 6.6
CPython 3.11.6
matplotlib 3.8.2

The table & plots below are just an attempt to nicely lay out the data generated using the code from the project repository's master branch. Visit https://github.com/egor-tensin/sorting-algorithms for more details.

Each of the implemented algorithms was provided with three input sequences:

  • a list of n consecutive numbers sorted in ascending order,
  • … in descending order,
  • … in random order.

Use the table below to quickly navigate to the plots for the corresponding algorithm.

Algorithm Complexity
Best Average Worst
Bubble sort O(n) O(n2) O(n2)
… "optimized" O(n) O(n2) O(n2)
Heapsort O(n log n) O(n log n) O(n log n)
Insertion sort O(n) O(n2) O(n2)
Merge sort O(n log n) O(n log n) O(n log n)
Quicksort (first element as pivot) O(n2) O(n log n) O(n2)
… second element… O(n2) O(n log n) O(n2)
… middle element… O(n log n) O(n log n) O(n log n)
… last element… O(n2) O(n log n) O(n2)
… random element… O(n log n) O(n log n) O(n log n)
Selection sort O(n2) O(n2) O(n2)

Bubble sort

Bubble sort, 100 iterations, best case
Bubble sort
Best case, O(n)
Bubble sort, 100 iterations, average case
Bubble sort
Average case, O(n2)
Bubble sort, 100 iterations, worst case
Bubble sort
Worst case, O(n2)

"Optimized" bubble sort

"Optimized" bubble sort, 100 iterations, best case
"Optimized" bubble sort
Best case, O(n)
"Optimized" bubble sort, 100 iterations, average case
"Optimized" bubble sort
Average case, O(n2)
"Optimized" bubble sort, 100 iterations, worst case
"Optimized" bubble sort
Worst case, O(n2)

Heapsort

Heapsort, 100 iterations, best case
Heapsort
Best case, O(n log n)
Heapsort, 100 iterations, average case
Heapsort
Average case, O(n log n)
Heapsort, 100 iterations, worst case
Heapsort
Worst case, O(n log n)

Insertion sort

Insertion sort, 100 iterations, best case
Insertion sort
Best case, O(n)
Insertion sort, 100 iterations, average case
Insertion sort
Average case, O(n2)
Insertion sort, 100 iterations, worst case
Insertion sort
Worst case, O(n2)

Merge sort

Merge sort, 100 iterations, best case
Merge sort
Best case, O(n log n)
Merge sort, 100 iterations, average case
Merge sort
Average case, O(n log n)
Merge sort, 100 iterations, worst case
Merge sort
Worst case, O(n log n)

Quicksort (first element as pivot)

Quicksort (first element as pivot), 100 iterations, best case
Quicksort (first element as pivot)
Best case, O(n2)
Quicksort (first element as pivot), 100 iterations, average case
Quicksort (first element as pivot)
Average case, O(n log n)
Quicksort (first element as pivot), 100 iterations, worst case
Quicksort (first element as pivot)
Worst case, O(n2)

Quicksort (second element as pivot)

Quicksort (second element as pivot), 100 iterations, best case
Quicksort (second element as pivot)
Best case, O(n2)
Quicksort (second element as pivot), 100 iterations, average case
Quicksort (second element as pivot)
Average case, O(n log n)
Quicksort (second element as pivot), 100 iterations, worst case
Quicksort (second element as pivot)
Worst case, O(n2)

Quicksort (middle element as pivot)

Quicksort (middle element as pivot), 100 iterations, best case
Quicksort (middle element as pivot)
Best case, O(n log n)
Quicksort (middle element as pivot), 100 iterations, average case
Quicksort (middle element as pivot)
Average case, O(n log n)
Quicksort (middle element as pivot), 100 iterations, worst case
Quicksort (middle element as pivot)
Worst case, O(n log n)

Quicksort (last element as pivot)

Quicksort (last element as pivot), 100 iterations, best case
Quicksort (last element as pivot)
Best case, O(n2)
Quicksort (last element as pivot), 100 iterations, average case
Quicksort (last element as pivot)
Average case, O(n log n)
Quicksort (last element as pivot), 100 iterations, worst case
Quicksort (last element as pivot)
Worst case, O(n2)

Quicksort (random element as pivot)

Quicksort (random element as pivot), 100 iterations, best case
Quicksort (random element as pivot)
Best case, O(n log n)
Quicksort (random element as pivot), 100 iterations, average case
Quicksort (random element as pivot)
Average case, O(n log n)
Quicksort (random element as pivot), 100 iterations, worst case
Quicksort (random element as pivot)
Worst case, O(n log n)

Selection sort

Selection sort, 100 iterations, best case
Selection sort
Best case, O(n2)
Selection sort, 100 iterations, average case
Selection sort
Average case, O(n2)
Selection sort, 100 iterations, worst case
Selection sort
Worst case, O(n2)