recursivo - quicksort python
Quicksort con Python (28)
Quicksort con Python
En la vida real, siempre debemos usar el tipo incorporado provisto por Python. Sin embargo, entender el algoritmo de quicksort es instructivo.
Mi objetivo aquí es desglosar el tema de modo que el lector lo pueda entender y reproducir fácilmente sin tener que regresar a los materiales de referencia.
El algoritmo de quicksort es esencialmente el siguiente:
- Seleccione un punto de datos de pivote.
- Mueva todos los puntos de datos por debajo de (debajo) el pivote a una posición debajo del pivote: mueva los que estén por encima o por encima (arriba) del pivote a una posición superior.
- Aplicar el algoritmo a las áreas arriba y debajo del pivote
Si los datos se distribuyen aleatoriamente, seleccionar el primer punto de datos como pivote equivale a una selección aleatoria.
Ejemplo legible:
Primero, veamos un ejemplo legible que usa comentarios y nombres de variables para apuntar a valores intermedios:
def quicksort(xs):
"""Given indexable and slicable iterable, return a sorted list"""
if xs: # if given list (or tuple) with one ordered item or more:
pivot = xs[0]
# below will be less than:
below = [i for i in xs[1:] if i < pivot]
# above will be greater than or equal to:
above = [i for i in xs[1:] if i >= pivot]
return quicksort(below) + [pivot] + quicksort(above)
else:
return xs # empty list
Para replantear el algoritmo y el código que se muestran aquí, movemos los valores por encima del pivote a la derecha y los valores por debajo del pivote a la izquierda, y luego pasamos esas particiones a la misma función para clasificarlas más.
Golfed:
Esto se puede jugar golf a 88 caracteres:
q=lambda x:x and q([i for i in x[1:]if i<=x[0]])+[x[0]]+q([i for i in x[1:]if i>x[0]])
Para ver cómo llegamos allí, primero tome nuestro ejemplo legible, elimine los comentarios y las cadenas de documentos, y encuentre el pivote en su lugar:
def quicksort(xs):
if xs:
below = [i for i in xs[1:] if i < xs[0]]
above = [i for i in xs[1:] if i >= xs[0]]
return quicksort(below) + [xs[0]] + quicksort(above)
else:
return xs
Ahora encuentra abajo y arriba, en el lugar:
def quicksort(xs):
if xs:
return (quicksort([i for i in xs[1:] if i < xs[0]] )
+ [xs[0]]
+ quicksort([i for i in xs[1:] if i >= xs[0]]))
else:
return xs
Ahora, sabiendo eso and
devuelve el elemento anterior si es falso, de lo contrario, si es verdadero, evalúa y devuelve el siguiente elemento, tenemos:
def quicksort(xs):
return xs and (quicksort([i for i in xs[1:] if i < xs[0]] )
+ [xs[0]]
+ quicksort([i for i in xs[1:] if i >= xs[0]]))
Dado que lambdas devuelve una sola epresión, y hemos simplificado a una sola expresión (a pesar de que cada vez es más ilegible), ahora podemos usar una lambda:
quicksort = lambda xs: (quicksort([i for i in xs[1:] if i < xs[0]] )
+ [xs[0]]
+ quicksort([i for i in xs[1:] if i >= xs[0]]))
Y para reducir nuestro ejemplo, acorte la función y los nombres de las variables a una letra, y elimine los espacios en blanco que no se requieren.
q=lambda x:x and q([i for i in x[1:]if i<=x[0]])+[x[0]]+q([i for i in x[1:]if i>x[0]])
Tenga en cuenta que este lambda, como la mayoría de los códigos de golf, es un estilo bastante malo.
Quicksort en el lugar, usando el esquema de Partición de Hoare
La implementación anterior crea muchas listas adicionales innecesarias. Si podemos hacer esto en el lugar, evitaremos desperdiciar espacio.
La implementación a continuación usa el esquema de particiones de Hoare, sobre el cual puede leer más sobre wikipedia (pero aparentemente hemos eliminado hasta 4 cálculos redundantes por llamada de partition()
usando la semántica while-loop en lugar de do-while y moviendo los pasos de estrechamiento a el final del ciclo while externo).
def quicksort(a_list):
"""Hoare partition scheme, see https://en.wikipedia.org/wiki/Quicksort"""
def _quicksort(a_list, low, high):
# must run partition on sections with 2 elements or more
if low < high:
p = partition(a_list, low, high)
_quicksort(a_list, low, p)
_quicksort(a_list, p+1, high)
def partition(a_list, low, high):
pivot = a_list[low]
while True:
while a_list[low] < pivot:
low += 1
while a_list[high] > pivot:
high -= 1
if low >= high:
return high
a_list[low], a_list[high] = a_list[high], a_list[low]
low += 1
high -= 1
_quicksort(a_list, 0, len(a_list)-1)
return a_list
No estoy seguro si lo probé lo suficiente:
def main():
assert quicksort([1]) == [1]
assert quicksort([1,2]) == [1,2]
assert quicksort([1,2,3]) == [1,2,3]
assert quicksort([1,2,3,4]) == [1,2,3,4]
assert quicksort([2,1,3,4]) == [1,2,3,4]
assert quicksort([1,3,2,4]) == [1,2,3,4]
assert quicksort([1,2,4,3]) == [1,2,3,4]
assert quicksort([2,1,1,1]) == [1,1,1,2]
assert quicksort([1,2,1,1]) == [1,1,1,2]
assert quicksort([1,1,2,1]) == [1,1,1,2]
assert quicksort([1,1,1,2]) == [1,1,1,2]
Conclusión
Este algoritmo se enseña con frecuencia en cursos de informática y se solicita entrevistas de trabajo. Nos ayuda a pensar en la recursión y divide y vencerás.
Quicksort no es muy práctico en Python ya que nuestro algoritmo de timsort incorporado es bastante eficiente, y tenemos límites de recursión. Esperaríamos ordenar las listas in situ con list.sort
o crear nuevas listas sorted
con sorted
; ambas tienen una key
y reverse
argumento reverse
.
Soy totalmente nuevo en Python y estoy tratando de implementar quicksort en él. ¿Podría alguien ayudarme a completar mi código?
No sé cómo concatenar las tres matrices e imprimirlas.
def sort(array=[12,4,5,6,7,3,1,15]):
less = []
equal = []
greater = []
if len(array) > 1:
pivot = array[0]
for x in array:
if x < pivot:
less.append(x)
if x == pivot:
equal.append(x)
if x > pivot:
greater.append(x)
sort(less)
sort(pivot)
sort(greater)
- Primero declaramos que el primer valor en la matriz es el valor_pivote y también establecemos las marcas izquierda y derecha
- Creamos el primer ciclo while, este while loop está ahí para decirle al proceso de partición que se ejecute nuevamente si no cumple con la condición necesaria
- luego aplicamos el proceso de partición
- después de que se hayan ejecutado ambos procesos de partición, verificamos si cumple la condición adecuada. Si lo hace, lo marcamos como hecho, si no cambiamos los valores de la izquierda y la derecha y lo aplicamos de nuevo
- Una vez hecho esto, cambie los valores de la izquierda y la derecha y devuelva el punto de división
¡Adjunto el código a continuación! Este quicksort es una gran herramienta de aprendizaje debido a la ubicación del valor de pivote . Como está en un lugar constante, puedes caminar varias veces y realmente entender cómo funciona todo. En la práctica, es mejor aleatorizar el pivote para evitar el tiempo de ejecución O (N ^ 2).
def quicksort10(alist):
quicksort_helper10(alist, 0, len(alist)-1)
def quicksort_helper10(alist, first, last):
""" """
if first < last:
split_point = partition10(alist, first, last)
quicksort_helper10(alist, first, split_point - 1)
quicksort_helper10(alist, split_point + 1, last)
def partition10(alist, first, last):
done = False
pivot_value = alist[first]
leftmark = first + 1
rightmark = last
while not done:
while leftmark <= rightmark and alist[leftmark] <= pivot_value:
leftmark = leftmark + 1
while leftmark <= rightmark and alist[rightmark] >= pivot_value:
rightmark = rightmark - 1
if leftmark > rightmark:
done = True
else:
temp = alist[leftmark]
alist[leftmark] = alist[rightmark]
alist[rightmark] = temp
temp = alist[first]
alist[first] = alist[rightmark]
alist[rightmark] = temp
return rightmark
Aquí hay una implementación fácil:
def quicksort(array):
if len(array) < 2:
return array
else:
pivot= array[0]
less = [i for i in array[1:] if i <= pivot]
greater = [i for i in array[1:] if i > pivot]
return quicksort(less) + [pivot] + quicksort(greater)
print(quicksort([10, 5, 2, 3]))
Clasificación rápida sin memoria adicional (en su lugar)
Uso:
array = [97, 200, 100, 101, 211, 107]
quicksort(array)
# array -> [97, 100, 101, 107, 200, 211]
def partition(array, begin, end):
pivot = begin
for i in xrange(begin+1, end+1):
if array[i] <= array[begin]:
pivot += 1
array[i], array[pivot] = array[pivot], array[i]
array[pivot], array[begin] = array[begin], array[pivot]
return pivot
def quicksort(array, begin=0, end=None):
if end is None:
end = len(array) - 1
def _quicksort(array, begin, end):
if begin >= end:
return
pivot = partition(array, begin, end)
_quicksort(array, begin, pivot-1)
_quicksort(array, pivot+1, end)
return _quicksort(array, begin, end)
Creo que ambas respuestas aquí funcionan bien para la lista proporcionada (que responde a la pregunta original), pero se romperían si se pasa una matriz que contiene valores no únicos. Entonces, para completar, solo señalaría el pequeño error en cada uno y explicaré cómo solucionarlos.
Por ejemplo, tratando de ordenar la siguiente matriz [12,4,5,6,7,3,1,15,1] (Tenga en cuenta que 1 aparece dos veces) con el algoritmo de ... en algún momento terminará con menos matriz vacía y la matriz igual con un par de valores (1,1) que no se pueden separar en la siguiente iteración y len ()> 1 ... por lo tanto, terminará con un ciclo infinito
Puede solucionarlo devolviendo el conjunto si hay menos vacío o mejor al no ordenar en su matriz igual, como en la respuesta
def sort(array=[12,4,5,6,7,3,1,15]):
less = []
equal = []
greater = []
if len(array) > 1:
pivot = array[0]
for x in array:
if x < pivot:
less.append(x)
if x == pivot:
equal.append(x)
if x > pivot:
greater.append(x)
# Don''t forget to return something!
return sort(less)+ equal +sort(greater) # Just use the + operator to join lists
# Note that you want equal ^^^^^ not pivot
else: # You need to hande the part at the end of the recursion - when you only have one element in your array, just return the array.
return array
La solución más elegante también se rompe, pero por una causa diferente, falta la cláusula return en la línea de recursión, lo que ocasionará que en algún momento devuelva None e intente agregarlo a una lista ....
Para solucionarlo solo agrega un retorno a esa línea
def qsort(arr):
if len(arr) <= 1:
return arr
else:
return qsort([x for x in arr[1:] if x<arr[0]]) + [arr[0]] + qsort([x for x in arr[1:] if x>=arr[0]])
Ejemplo completo con variables impresas en el paso de la partición:
def partition(data, p, right):
print("/n==> Enter partition: p={}, right={}".format(p, right))
pivot = data[right]
print("pivot = data[{}] = {}".format(right, pivot))
i = p - 1 # this is a dangerous line
for j in range(p, right):
print("j: {}".format(j))
if data[j] <= pivot:
i = i + 1
print("new i: {}".format(i))
print("swap: {} <-> {}".format(data[i], data[j]))
data[i], data[j] = data[j], data[i]
print("swap2: {} <-> {}".format(data[i + 1], data[right]))
data[i + 1], data[right] = data[right], data[i + 1]
return i + 1
def quick_sort(data, left, right):
if left < right:
pivot = partition(data, left, right)
quick_sort(data, left, pivot - 1)
quick_sort(data, pivot + 1, right)
data = [2, 8, 7, 1, 3, 5, 6, 4]
print("Input array: {}".format(data))
quick_sort(data, 0, len(data) - 1)
print("Output array: {}".format(data))
El algoritmo tiene 4 pasos simples:
- Divida la matriz en 3 partes diferentes: izquierda, pivote y derecha, donde el pivote tendrá solo un elemento. Vamos a elegir este elemento pivote como el primer elemento de matriz
- Añada elementos a la parte respectiva comparándolos con el elemento pivote. (explicación en comentarios)
- Repita este algoritmo hasta que todos los elementos de la matriz hayan sido ordenados
- Finalmente, unir las partes izquierda + pivote + derecha
Código para el algoritmo en python:
def my_sort(A):
p=A[0] #determine pivot element.
left=[] #create left array
right=[] #create right array
for i in range(1,len(A)):
#if cur elem is less than pivot, add elem in left array
if A[i]< p:
left.append(A[i])
#the recurssion will occur only if the left array is atleast half the size of original array
if len(left)>1 and len(left)>=len(A)//2:
left=my_sort(left) #recursive call
elif A[i]>p:
right.append(A[i]) #if elem is greater than pivot, append it to right array
if len(right)>1 and len(right)>=len(A)//2: # recurssion will occur only if length of right array is atleast the size of original array
right=my_sort(right)
A=left+[p]+right #append all three part of the array into one and return it
return A
my_sort([12,4,5,6,7,3,1,15])
Continúa con este algoritmo recursivamente con las partes izquierda y derecha.
Esta es una versión del quicksort que usa el esquema de partición Hoare y con menos swaps y variables locales
def quicksort(array):
qsort(array, 0, len(array)-1)
def qsort(A, lo, hi):
if lo < hi:
p = partition(A, lo, hi)
qsort(A, lo, p)
qsort(A, p + 1, hi)
def partition(A, lo, hi):
pivot = A[lo]
i, j = lo-1, hi+1
while True:
i += 1
j -= 1
while(A[i] < pivot): i+= 1
while(A[j] > pivot ): j-= 1
if i >= j:
return j
A[i], A[j] = A[j], A[i]
test = [21, 4, 1, 3, 9, 20, 25, 6, 21, 14]
print quicksort(test)
Hay otra versión concisa y hermosa
def qsort(arr):
if len(arr) <= 1:
return arr
else:
return qsort([x for x in arr[1:] if x<arr[0]]) + [arr[0]] + qsort([x for x in arr[1:] if x>=arr[0]])
# this comment is just to improve readability due to horizontal scroll!!!
Permítanme explicar los códigos anteriores para más detalles
elige el primer elemento de la matriz
arr[0]
como pivote[arr[0]]
qsort
esos elementos de matriz que son menos que pivote conList Comprehension
qsort([x for x in arr[1:] if x<arr[0]])
qsort
aquellos elementos de matriz que son más grandes que pivote conList Comprehension
qsort([x for x in arr[1:] if x>=arr[0]])
O si prefiere una línea que también ilustre el equivalente de Python de varags C / C ++, expresiones lambda y expresiones if:
qsort = lambda x=None, *xs: [] if x is None else qsort(*[a for a in xs if a<x]) + [x] + qsort(*[a for a in xs if a>=x])
Otra implementación de quicksort:
# A = Array
# s = start index
# e = end index
# p = pivot index
# g = greater than pivot boundary index
def swap(A,i1,i2):
A[i1], A[i2] = A[i2], A[i1]
def partition(A,g,p):
# O(n) - just one for loop that visits each element once
for j in range(g,p):
if A[j] <= A[p]:
swap(A,j,g)
g += 1
swap(A,p,g)
return g
def _quicksort(A,s,e):
# Base case - we are sorting an array of size 1
if s >= e:
return
# Partition current array
p = partition(A,s,e)
_quicksort(A,s,p-1) # Left side of pivot
_quicksort(A,p+1,e) # Right side of pivot
# Wrapper function for the recursive one
def quicksort(A):
_quicksort(A,0,len(A)-1)
A = [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,-1]
print(A)
quicksort(A)
print(A)
Si busco "implementación de python quicksort" en Google, esta pregunta es el primer resultado que aparecerá. Entiendo que la pregunta inicial fue "ayudar a corregir el código", pero ya hay muchas respuestas que no tienen en cuenta esa solicitud: la segunda más votada en la actualidad, el horrendo juego de one-liner con el hilarante comentario "Estás despedido" y, en general , muchas implementaciones que no están en su lugar (es decir, usan memoria extra proporcional al tamaño de la lista de entrada). Esta respuesta proporciona una solución en el lugar pero es para python 2.x
Por lo tanto, a continuación sigue mi interpretación de la solución in situ de Rosetta Code, que también funcionará bien para python 3
:
import random
def qsort(l, fst, lst):
if fst >= lst: return
i, j = fst, lst
pivot = l[random.randint(fst, lst)]
while i <= j:
while l[i] < pivot: i += 1
while l[j] > pivot: j -= 1
if i <= j:
l[i], l[j] = l[j], l[i]
i, j = i + 1, j - 1
qsort(l, fst, j)
qsort(l, i, lst)
Y si está dispuesto a renunciar a la propiedad en el lugar, a continuación hay otra versión que ilustra mejor las ideas básicas detrás del servicio rápido. Además de la legibilidad, su otra ventaja es que es estable (los elementos iguales aparecen en la lista ordenada en el mismo orden que solían tener en la lista desordenada). Esta propiedad de estabilidad no se cumple con la implementación in situ menos hambrienta de memoria presentada anteriormente.
def qsort(l):
if not l: return l # empty sequence case
pivot = l[random.choice(range(0, len(l)))]
head = qsort([elem for elem in l if elem < pivot])
tail = qsort([elem for elem in l if elem > pivot])
return head + [elem for elem in l if elem == pivot] + tail
Una implementación in situ "verdadera" [Algoritmos 8.9, 8.11 del Libro de Diseño y Aplicaciones de Algoritmos de Michael T. Goodrich y Roberto Tamassia]:
from random import randint
def partition (A, a, b):
p = randint(a,b)
# or mid point
# p = (a + b) / 2
piv = A[p]
# swap the pivot with the end of the array
A[p] = A[b]
A[b] = piv
i = a # left index (right movement ->)
j = b - 1 # right index (left movement <-)
while i <= j:
# move right if smaller/eq than/to piv
while A[i] <= piv and i <= j:
i += 1
# move left if greater/eq than/to piv
while A[j] >= piv and j >= i:
j -= 1
# indices stopped moving:
if i < j:
# swap
t = A[i]
A[i] = A[j]
A[j] = t
# place pivot back in the right place
# all values < pivot are to its left and
# all values > pivot are to its right
A[b] = A[i]
A[i] = piv
return i
def IpQuickSort (A, a, b):
while a < b:
p = partition(A, a, b) # p is pivot''s location
#sort the smaller partition
if p - a < b - p:
IpQuickSort(A,a,p-1)
a = p + 1 # partition less than p is sorted
else:
IpQuickSort(A,p+1,b)
b = p - 1 # partition greater than p is sorted
def main():
A = [12,3,5,4,7,3,1,3]
print A
IpQuickSort(A,0,len(A)-1)
print A
if __name__ == "__main__": main()
Ya hay muchas respuestas a esto, pero creo que este enfoque es la implementación más limpia:
def quicksort(arr):
""" Quicksort a list
:type arr: list
:param arr: List to sort
:returns: list -- Sorted list
"""
if not arr:
return []
pivots = [x for x in arr if x == arr[0]]
lesser = quicksort([x for x in arr if x < arr[0]])
greater = quicksort([x for x in arr if x > arr[0]])
return lesser + pivots + greater
Por supuesto, puede omitir el almacenamiento de todo en variables y devolverlas de inmediato así:
def quicksort(arr):
""" Quicksort a list
:type arr: list
:param arr: List to sort
:returns: list -- Sorted list
"""
if not arr:
return []
return quicksort([x for x in arr if x < arr[0]]) /
+ [x for x in arr if x == arr[0]] /
+ quicksort([x for x in arr if x > arr[0]])
enfoque de programación funcional
smaller = lambda xs, y: filter(lambda x: x <= y, xs)
larger = lambda xs, y: filter(lambda x: x > y, xs)
qsort = lambda xs: qsort(smaller(xs[1:],xs[0])) + [xs[0]] + qsort(larger(xs[1:],xs[0])) if xs != [] else []
print qsort([3,1,4,2,5]) == [1,2,3,4,5]
enfoque funcional:
def qsort(list):
if len(list) < 2:
return list
pivot = list.pop()
left = filter(lambda x: x <= pivot, list)
right = filter(lambda x: x > pivot, list)
return qsort(left) + [pivot] + qsort(right)
tipo inlace
def qsort(a, b=0, e=None):
# partitioning
def part(a, start, end):
p = start
for i in xrange(start+1, end):
if a[i] < a[p]:
a[i], a[p+1] = a[p+1], a[i]
a[p+1], a[p] = a[p], a[p+1]
p += 1
return p
if e is None:
e = len(a)
if e-b <= 1: return
p = part(a, b, e)
qsort(a, b, p)
qsort(a, p+1, e)
sin recursión:
deq = collections.deque()
deq.append((b, e))
while len(deq):
el = deq.pop()
if el[1] - el[0] > 1:
p = part(a, el[0], el[1])
deq.append((el[0], p))
deq.append((p+1, el[1]))
Partición : divida una matriz por un pivote para que los elementos más pequeños se muevan hacia la izquierda y los elementos más grandes se muevan hacia la derecha o viceversa. Un pivote puede ser un elemento aleatorio de una matriz. Para hacer este algoritmo, necesitamos saber qué es el índice inicial y final de una matriz y dónde se encuentra un pivote. Luego configure dos punteros auxiliares L, R.
Entonces, tenemos un usuario de matriz [..., begin, ..., end, ...]
La posición de inicio de los punteros L y R
[..., comenzar, siguiente, ..., fin, ...]
R L
mientras que L <fin
1. Si un usuario [pivote]> usuario [L], mueva R por uno e intercambie usuario [R] con usuario [L]
2. mueve L por uno
Después, al intercambiar usuario [R] con usuario [pivote]
Clasificación rápida : utilice el algoritmo de partición hasta que cada parte siguiente de la división por un pivote tenga un índice de inicio mayor o igual que el índice final.
def qsort(user, begin, end):
if begin >= end:
return
# partition
# pivot = begin
L = begin+1
R = begin
while L < end:
if user[begin] > user[L]:
R+=1
user[R], user[L] = user[L], user[R]
L+= 1
user[R], user[begin] = user[begin], user[R]
qsort(user, 0, R)
qsort(user, R+1, end)
tests = [
{''sample'':[1],''answer'':[1]},
{''sample'':[3,9],''answer'':[3,9]},
{''sample'':[1,8,1],''answer'':[1,1,8]},
{''sample'':[7,5,5,1],''answer'':[1,5,5,7]},
{''sample'':[4,10,5,9,3],''answer'':[3,4,5,9,10]},
{''sample'':[6,6,3,8,7,7],''answer'':[3,6,6,7,7,8]},
{''sample'':[3,6,7,2,4,5,4],''answer'':[2,3,4,4,5,6,7]},
{''sample'':[1,5,6,1,9,0,7,4],''answer'':[0,1,1,4,5,6,7,9]},
{''sample'':[0,9,5,2,2,5,8,3,8],''answer'':[0,2,2,3,5,5,8,8,9]},
{''sample'':[2,5,3,3,2,0,9,0,0,7],''answer'':[0,0,0,2,2,3,3,5,7,9]}
]
for test in tests:
sample = test[''sample''][:]
answer = test[''answer'']
qsort(sample,0,len(sample))
print(sample == answer)
Para la Versión Python 3.x : un estilo funcional que usa un módulo de operator
, principalmente para mejorar la legibilidad.
from operator import ge as greater, lt as lesser
def qsort(L):
if len(L) <= 1: return L
pivot = L[0]
sublist = lambda op: [*filter(lambda num: op(num, pivot), L[1:])]
return qsort(sublist(lesser))+ [pivot] + qsort(sublist(greater))
y se prueba como
print (qsort([3,1,4,2,5]) == [1,2,3,4,5])
I will do quicksort using numpy library. I think it is really usefull library. They already implemented the quick sort method but you can implment also your custom method.
import numpy
array = [3,4,8,1,2,13,28,11,99,76] #The array what we want to sort
indexes = numpy.argsort( array , None, ''quicksort'', None)
index_list = list(indexes)
temp_array = []
for index in index_list:
temp_array.append( array[index])
array = temp_array
print array #it will show sorted array
Instead of taking three different arrays for less equal greater and then concatenating all try the traditional concept(partitioning method):
http://pythonplanet.blogspot.in/2015/08/quick-sort-using-traditional-partition.html
this is without using any inbuilt function.
partitioning function -
def partitn(alist, left, right):
i=left
j=right
mid=(left+right)/2
pivot=alist[mid]
while i <= j:
while alist[i] < pivot:
i=i+1
while alist[j] > pivot:
j=j-1
if i <= j:
temp = alist[i]
alist[i] = alist[j]
alist[j] = temp
i = i + 1
j = j - 1
def Partition(A,p,q):
i=p
x=A[i]
for j in range(p+1,q+1):
if A[j]<=x:
i=i+1
tmp=A[j]
A[j]=A[i]
A[i]=tmp
l=A[p]
A[p]=A[i]
A[i]=l
return i
def quickSort(A,p,q):
if p<q:
r=Partition(A,p,q)
quickSort(A,p,r-1)
quickSort(A,r+1,q)
return A
def quick_sort(array):
return quick_sort([x for x in array[1:] if x < array[0]]) + [array[0]] /
+ quick_sort([x for x in array[1:] if x >= array[0]]) if array else []
def quick_sort(l):
if len(l) == 0:
return l
pivot = l[0]
pivots = [x for x in l if x == pivot]
smaller = quick_sort([x for x in l if x < pivot])
larger = quick_sort([x for x in l if x > pivot])
return smaller + pivots + larger
def quick_sort(list):
if len(list) ==0:
return []
return quick_sort(filter( lambda item: item < list[0],list)) + [v for v in list if v==list[0] ] + quick_sort( filter( lambda item: item > list[0], list))
def quick_sort(self, nums):
def helper(arr):
if len(arr) <= 1: return arr
#lwall is the index of the first element euqal to pivot
#rwall is the index of the first element greater than pivot
#so arr[lwall:rwall] is exactly the middle part equal to pivot after one round
lwall, rwall, pivot = 0, 0, 0
#choose rightmost as pivot
pivot = arr[-1]
for i, e in enumerate(arr):
if e < pivot:
#when element is less than pivot, shift the whole middle part to the right by 1
arr[i], arr[lwall] = arr[lwall], arr[i]
lwall += 1
arr[i], arr[rwall] = arr[rwall], arr[i]
rwall += 1
elif e == pivot:
#when element equals to pivot, middle part should increase by 1
arr[i], arr[rwall] = arr[rwall], arr[i]
rwall += 1
elif e > pivot: continue
return helper(arr[:lwall]) + arr[lwall:rwall] + helper(arr[rwall:])
return helper(nums)
def quicksort(items):
if not len(items) > 1:
return items
items, pivot = partition(items)
return quicksort(items[:pivot]) + [items[pivot]] + quicksort(items[pivot + 1:])
def partition(items):
i = 1
pivot = 0
for j in range(1, len(items)):
if items[j] <= items[pivot]:
items[i], items[j] = items[j], items[i]
i += 1
items[i - 1], items[pivot] = items[pivot], items[i - 1]
return items, i - 1
def sort(array=[12,4,5,6,7,3,1,15]):
less = []
equal = []
greater = []
if len(array) > 1:
pivot = array[0]
for x in array:
if x < pivot:
less.append(x)
if x == pivot:
equal.append(x)
if x > pivot:
greater.append(x)
# Don''t forget to return something!
return sort(less)+equal+sort(greater) # Just use the + operator to join lists
# Note that you want equal ^^^^^ not pivot
else: # You need to hande the part at the end of the recursion - when you only have one element in your array, just return the array.
return array