En clase estamos haciendo algoritmos de clasificación y, aunque los entiendo bien cuando hablo de ellos y escribo pseudocódigo, tengo problemas para escribir código real para ellos.
Este es mi intento en Python:
mylist = [12, 5, 13, 8, 9, 65]
def bubble(badList):
length = len(badList) - 1
unsorted = True
while unsorted:
for element in range(0,length):
unsorted = False
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
print badList
else:
unsorted = True
print bubble(mylist)
Ahora, esto (por lo que puedo decir) se ordena correctamente, pero una vez que termina, se repite indefinidamente.
¿Cómo se puede corregir este código para que la función finalice correctamente y clasifique correctamente una lista de cualquier tamaño (razonable)?
PD: Sé que realmente no debería tener impresiones en una función y debería tener una devolución, pero aún no lo he hecho ya que mi código aún no funciona.
python
algorithm
sorting
bubble-sort
Josh Hunt
fuente
fuente
Respuestas:
Para explicar por qué su script no funciona en este momento, cambiaré el nombre de la variable
unsorted
asorted
.Al principio, tu lista aún no está ordenada. Por supuesto, nos pusimos
sorted
aFalse
.Tan pronto como comenzamos el
while
ciclo, asumimos que la lista ya está ordenada. La idea es esta: en cuanto encontramos dos elementos que no están en el orden correcto, volvemossorted
aFalse
. solosorted
permaneceráTrue
si no hay elementos en el orden incorrecto .También hay pequeños problemas menores que ayudarían a que el código sea más eficiente o legible.
En el
for
ciclo, usas la variableelement
. Técnicamente,element
no es un elemento; Es un número que representa un índice de lista. Además, es bastante largo. En estos casos, simplemente use un nombre de variable temporal, comoi
"index".El
range
comando también puede tomar solo un argumento (llamadostop
). En ese caso, obtienes una lista de todos los enteros de 0 a ese argumento.La Guía de estilo de Python recomienda que las variables se nombren en minúsculas con guiones bajos. Este es un pequeño detalle para un pequeño guión como este; es más para acostumbrarte a lo que el código de Python se parece más a menudo.
Para intercambiar los valores de dos variables, escríbalas como una asignación de tupla. El lado derecho se evalúa como una tupla (por ejemplo,
(badList[i+1], badList[i])
es(3, 5)
) y luego se asigna a las dos variables en el lado izquierdo ((badList[i], badList[i+1])
).Póngalo todo junto y obtendrá esto:
(Por cierto, también eliminé tu declaración impresa).
fuente
while
bucle, el elemento más grande "aparece" al final de la lista. Como tal, después de una iteración, el último elemento está definitivamente en el lugar correcto (y no se moverá por iteraciones sucesivas). Al restar 1 de la longitud, está optimizando el algoritmo al ordenar solo la sublista que aún no está ordenada (loslength-n
elementos más avanzados de la lista). Elegí omitir esta optimización, ya que es más una optimización que una parte vital del algoritmo.Put it all together, and you get this:
... bueno, te perdiste este:The range command can also take just one argument (named stop).
El objetivo de la clasificación de burbujas es mover los elementos más pesados en la parte inferior en cada ronda, mientras se mueven los elementos más ligeros hacia arriba. En el bucle interno, donde compara los elementos, no tiene que iterar la lista completa en cada turno . El más pesado ya está colocado en último lugar. La variable intercambiada es una verificación adicional para que podamos marcar que la lista ahora está ordenada y evitar continuar con cálculos innecesarios.
Su versión 1, corregida:
fuente
Esto es lo que sucede cuando usa un nombre de variable de significado negativo, necesita invertir sus valores. Lo siguiente sería más fácil de entender:
Por otro lado, la lógica del algoritmo está un poco apagada. Debe verificar si dos elementos se intercambiaron durante el ciclo for. Así es como lo escribiría:
fuente
Su uso de la variable sin clasificar es incorrecto; desea tener una variable que le indique si ha intercambiado dos elementos; Si lo ha hecho, puede salir de su bucle, de lo contrario, debe volver a hacerlo. Para arreglar lo que tiene aquí, simplemente ponga "unsorted = false" en el cuerpo de su caso if; retire su caso más; y pon "unsorted = true antes de tu
for
ciclo.fuente
fuente
# Una función muy simple, se puede optimizar (obviamente) disminuyendo el espacio del problema de la segunda matriz. Pero la misma complejidad O (n ^ 2).
fuente
arr[a], arr[b] = arr[b], arr[a]
Tienes un par de errores allí. El primero es de longitud y el segundo está en el uso de sin clasificar (como lo indica McWafflestix). Probablemente también desee devolver la lista si va a imprimirla:
eta: Tienes razón, lo anterior está lleno de errores como el infierno. Mi mal por no probar a través de algunos ejemplos más.
fuente
Soy un principiante fresco, comencé a leer sobre Python ayer. Inspirado por tu ejemplo, creé algo tal vez más en el estilo de los 80 lazos, pero de todos modos funciona
fuente
El problema con el algoritmo original es que si tuviera un número más bajo en la lista, no lo colocaría en la posición ordenada correcta. El programa debe volver al principio cada vez para asegurarse de que los números se ordenen por completo.
Simplifiqué el código y ahora funcionará para cualquier lista de números, independientemente de la lista e incluso si hay números repetidos. Aquí está el código
fuente
fuente
alist = [54,26,93,17,77,31,44,55,20, -23, -34,16,11,11,11]
print bubbleSort (lista)
fuente
fuente
Un ejemplo más simple:
Esto simplemente toma los elementos de 0 a a (básicamente, todos los elementos sin clasificar en esa ronda) y lo compara con su elemento adyacente, y realiza un intercambio si es mayor que su elemento adyacente. Al final de la ronda, se ordena el último elemento y el proceso se ejecuta nuevamente sin él, hasta que se hayan ordenado todos los elementos.
No hay necesidad de una condición, ya
sort
sea verdadera o no.Tenga en cuenta que este algoritmo toma en consideración la posición de los números solo cuando se intercambia, por lo que los números repetidos no lo afectarán.
PD. Sé que ha pasado mucho tiempo desde que se publicó esta pregunta, pero solo quería compartir esta idea.
fuente
fuente
fuente
fuente
fuente
Considero agregar mi solución porque alguna solución aquí es tener
entonces es debería ser
Entonces, aquí está mi solución:
fuente
Si alguien está interesado en una implementación más corta utilizando una lista de comprensión:
fuente
Aquí hay una variación diferente del tipo de burbuja sin
for
bucle. Básicamente estás considerando ellastIndex
dearray
y lentamentedecrementing
hasta su primer índice de la matriz.El
algorithm
continuará moviéndose a través de la matriz de esta manera hasta que se realice un pase completo sin queswaps
ocurra nada .La burbuja es básicamente
Quadratic Time: O(n²)
en lo que respecta al rendimiento.fuente
Las respuestas proporcionadas por the-fury y Martin Cote solucionaron el problema del bucle infinito, pero mi código aún no funcionaría correctamente (para una lista más grande, no se ordenaría correctamente). Terminé abandonando la
unsorted
variable y usé un contador en su lugar.Si alguien pudiera proporcionar sugerencias sobre cómo mejorar mi código en los comentarios, sería muy apreciado.
fuente
Prueba esto
fuente
idk si esto podría ayudarte después de 9 años ... es un simple programa de clasificación de burbujas
fuente
fuente
fuente
fuente
def bubbleSort(a): def swap(x, y): temp = a[x] a[x] = a[y] a[y] = temp #outer loop for j in range(len(a)): #slicing to the center, inner loop, python style for i in range(j, len(a) - j):
#find the min index and swap if a[i] < a[j]: swap(j, i) #find the max index and swap if a[i] > a[len(a) - j - 1]: swap(len(a) - j - 1, i) return a
fuente