- Los ordenamientos de selección e inserción, presentados en la unidad anterior son ordenamientos sencillos pero que costosos en cantidad de intercambios o de comparaciones. Sin embargo, es posible conseguir ordenamientos con mejor orden utilizando algoritmos recursivos.
- El algoritmo Merge Sort consiste en dividir la lista a ordenar
hasta que tenga
1
o0
elementos y luego combinar la lista de forma ordenada. De esta manera se logra un tiempo proporcional aN x logN
. Tiene como desventaja que siempre utiliza el doble de la memoria requerida por la lista a ordenar. - El algoritmo Quick Sort consiste en elegir un elemento, llamado
pivote y ordenar los elementos de tal forma que todos los menores
queden a la izquierda y todos los mayores a la derecha, y a
continuación ordenar de la misma forma cada una de las dos sublistas
formadas. Puede implementarse de tal forma que opere sobre la misma
lista, sin necesidad de utilizar más memoria. Tiene como desventaja
que si bien en el caso promedio tarda
N x log N
, en el peor caso (según cuál sea el pivote elegido) puede llegar a tardarN^2
.
# Código 20.3: quicksort.py: Una versión más eficiente de *Quicksort*
#/usr/bin/env python
#encoding: latin1
def quick_sort(lista):
""" Ordena la lista de forma recursiva.
Pre: los elementos de la lista deben ser comparables.
Post: la lista está ordenada. """
quick_sort(lista, 0, len(lista) - 1)
def _quick_sort(lista, inicio, fin):
""" Función quick_sort recursiva.
Pre: los índices inicio y fin indican sobre qué porción operar.
Post: la lista está ordenada.
"""
# Caso base
if inicio >= fin:
return
# Caso recursivo
menores = _partition(lista, inicio, fin)
_quick_sort(lista, inicio, menores - 1)
_quick_sort(lista, menores + 1, fin)
def _partition(lista, inicio, fin):
""" Función partición que trabaja sobre la misma lista.
Pre: los índices inicio y fin indican sobre qué porción operar.
Post: los menores están antes que el pivote, los mayores después.
Devuelve: la posición en la que quedó ubicado el pivote. """
pivote = lista[inicio]
menores = inicio
# Cambia de lugar los elementos
for i in xrange(inicio+1, fin + 1):
if lista[i] < pivote:
menores += 1
if i != menores:
_swap(lista, i, menores)
# Pone el pivote al final de los menores
if inicio != menores:
_swap(lista, inicio, menores)
# Devuelve la posición del pivote
return menores
def _swap(lista, i, j):
""" Intercambia los elementos i y j de lista. """
lista[j], lista[i] = lista[i], lista[j]
Copyright (c) 2011-2014 Rosita Wachenchauzer, Margarita Manterola,
Maximiliano Curia, Marcos Medrano, Nicolás Paez.
La copia y redistribución de esta página se permite bajo los términos
de la licencia Creative Commons Atribución - Compartir Obras Derivadas
Igual 3.0 siempre que se conserve esta nota de copyright.