Using the standard order of natural numbers $\mathbb{N}$
[1, 3, 10, 15, 16]
- is sorted
[1, 3, 15, 10]
- is not sorted ($15 < 10$)
A sorting algorithm is called stable if it keeps elements that are equivalent according to the sort order in the same order as they appear in the input
Example: sorting Persons(Name,Age)
on their Age
[(Peter,30), (Alice,25), (Bob,30)]
Any stable sorting algorithm will produce this result:
[(Alice,25), (Peter,30), (Bob,30)]
def bubble_sort(lst):
for i in range(1, len(lst)):
for j in range(1, len(lst)):
if lst[j] < lst[j-1]:
lst[j], lst[j-1] = lst[j-1], lst[j]
def bubble_sort(lst):
for i in range(1, len(lst)):
for j in range(1, len(lst)):
if lst[j] < lst[j-1]:
lst[j], lst[j-1] = lst[j-1], lst[j]
def insertion_sort(lst):
for i in range(1, len(lst)): # after i iterations the first i elements are sorted
for j in range(i, 0, -1): # trickle the ith element down to its position withing this sorted list
if lst[j] < lst[j-1]:
lst[j], lst[j-1] = lst[j-1], lst[j]
else:
break # found final position of element
def insertion_sort(lst):
for i in range(1, len(lst)): # after i iterations the first i elements are sorted
for j in range(i, 0, -1): # trickle the ith element down to its position withing this sorted list
if lst[j] < lst[j-1]:
lst[j], lst[j-1] = lst[j-1], lst[j]
else:
break # found final position of element
def insertion_sort(lst):
for i in range(1, len(lst)): # after i iterations the first i elements are sorted
for j in range(i, 0, -1): # trickle the ith element down to its position withing this sorted list
if lst[j] < lst[j-1]:
lst[j], lst[j-1] = lst[j-1], lst[j]
else:
break # found final position of element
def insertion_sort(lst):
for i in range(1, len(lst)): # after i iterations the first i elements are sorted
for j in range(i, 0, -1): # trickle the ith element down to its position withing this sorted list
if lst[j] < lst[j-1]:
lst[j], lst[j-1] = lst[j-1], lst[j]
else:
break # found final position of element
def counting_sort(lst):
for i in range(1, len(lst)): # after i iterations the first i elements are sorted
for j in range(i, 0, -1): # trickle the ith element down to its position withing this sorted list
if lst[j] < lst[j-1]:
lst[j], lst[j-1] = lst[j-1], lst[j]
else:
break # found final position of element
Algorithm | Worst-case | Average-case | Best-case |
---|---|---|---|
Bubble sort | $O(n^2)$ | $O(n^2)$ | $O(n^2)$ |
Insertion sort | $O(n^2)$ | $O(n^2)$ | $O(n^2)$ |
Heap sort | $O(n \cdot\log n)$ | $O(n \cdot\log n)$ | $O(n \cdot\log n)$ |
Merge sort | $O(n \cdot\log n)$ | $O(n \cdot\log n)$ | $O(n \cdot\log n)$ |
Quick sort | $O(n^2)$ | $O(n \cdot\log n)$ | $O(n \cdot\log n)$ |
Counting sort | $O(n)$ | $O(n)$ | $O(n)$ |
Note that, however, counting sort needs $O(m)$ memory where $m$ is the size of the domain of elements, e.g., for 64-bit integers there are $2^{64} = 18,446,744,073,709,551,616$ elements in the domain. Also to address these elements in an array we need $O(\log m)$ time.
Algorithm | Worst-case | Average-case | Best-case |
---|---|---|---|
Countingsort | $O(n \cdot d)$ | $O(n \cdot d)$ | $O(n \cdot d)$ |
Radixsort |