"""
This is a pure Python implementation of the radix sort algorithm
Source: https://en.wikipedia.org/wiki/Radix_sort
"""
from __future__ import annotations
RADIX = 10
def radix_sort(list_of_ints: list[int]) -> list[int]:
"""
Examples:
>>> radix_sort([0, 5, 3, 2, 2])
[0, 2, 2, 3, 5]
>>> radix_sort(list(range(15))) == sorted(range(15))
True
>>> radix_sort(list(range(14,-1,-1))) == sorted(range(15))
True
>>> radix_sort([1,100,10,1000]) == sorted([1,100,10,1000])
True
"""
placement = 1
max_digit = max(list_of_ints)
while placement <= max_digit:
# declare and initialize empty buckets
buckets: list[list] = [[] for _ in range(RADIX)]
# split list_of_ints between the buckets
for i in list_of_ints:
tmp = int((i / placement) % RADIX)
buckets[tmp].append(i)
# put each buckets' contents into list_of_ints
a = 0
for b in range(RADIX):
for i in buckets[b]:
list_of_ints[a] = i
a += 1
# move to next
placement *= RADIX
return list_of_ints
if __name__ == "__main__":
import doctest
doctest.testmod()
El l铆mite inferior para el algoritmo de ordenaci贸n basado en comparaci贸n (Orden de fusi贸n, Ordenaci贸n de mont贸n, Ordenaci贸n r谩pida, etc.) es 惟(nlogn)
, es decir, no pueden hacerlo mejor que nlogn
.
La ordenaci贸n del recuento es un algoritmo de ordenaci贸n de tiempo lineal que ordena en el tiempo O(n+k)
cuando los elementos est谩n en el rango de 1 a k.
驴Qu茅 sucede si los elementos est谩n en el rango de 1 a n2? No podemos usar la ordenaci贸n de recuento, porque la ordenaci贸n de recuento tomar谩 O(n2)
, que es peor que los algoritmos de clasificaci贸n basados en comparaci贸n. 驴Podemos ordenar una matriz de este tipo en tiempo lineal?
Radix Sort es la respuesta. La idea de Radix Sort es hacer orden d铆gito por d铆gito a partir de un d铆gito menos significativo a un d铆gito m谩s significativo. La ordenaci贸n de radios utiliza la ordenaci贸n de recuento como subrutina para ordenar.
Haga lo siguiente para cada d铆gito i donde var铆a de un d铆gito menos significativo al d铆gito m谩s significativo. Ordene la matriz de entrada mediante la ordenaci贸n de recuento (o cualquier ordenaci贸n estable) seg煤n el d铆gito i'th.
Ejemplo:
Lista original y no ordenada:
170, 45, 75, 90, 802, 24, 2, 66
Ordenar por el d铆gito menos significativo (lugar 1s) da:
[*Observe que mantenemos el 802 antes de las 2, porque ocurri贸 el 802 antes de 2 en la lista original, y de manera similar para los pares 170 &90 y 45 &75.]
Ordenar por el siguiente d铆gito (lugar de los a帽os 10) da:
[*Observe que 802 de nuevo viene antes de 2 como 802 viene antes de 2 en la lista anterior.]
802, 2, 24, 45, 66, 170, 75, 90
La clasificaci贸n por el d铆gito m谩s significativo (lugar de los a帽os 100) da:
2, 24, 45, 66, 75, 90, 170, 802
Deje que haya d铆gitos d
en los enteros de entrada. Radix Sort toma O(d*(n+b))
tiempo donde b
es la base para representar n煤meros, por ejemplo, para el sistema decimal, b
es 10.
驴Cu谩l es el valor de d
? Si k
es el valor m谩ximo posible, entonces ser铆a O(logb(k))
. As铆 que la complejidad general temporal es O((n+b) * logb(k))
. Lo que parece m谩s que el
complejidad temporal de algoritmos de ordenaci贸n basados en comparaci贸n para una k
grande. Limitemos primero k
. Deje k <= nc
donde c
es una constante. En ese caso, la complejidad se convierte en
O(n logb(n))
. Pero todav铆a no supera los algoritmos de clasificaci贸n basados en comparaci贸n.
Si, tenemos bits log2n
para cada d铆gito, el tiempo de ejecuci贸n de Radix parece ser mejor que la ordenaci贸n r谩pida para una amplia gama de n煤meros de entrada. Los factores constantes ocultos en la notaci贸n asint贸tica, son mayores para Radix Sort y Quick-Sort que utiliza cach茅s de hardware de forma m谩s eficaz. Adem谩s, Radix sort utiliza la ordenaci贸n de recuento como una subrutina y la ordenaci贸n de recuento
necesita espacio adicional para ordenar los n煤meros.
V铆deo de referencia: https://youtu.be/nu4gDuFabIM