Na aula, estamos desenvolvendo algoritmos de classificação e, embora eu os entenda bem ao falar sobre eles e ao escrever pseudocódigo, estou tendo problemas para escrever o código real para eles.
Esta é a minha tentativa em 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)
Agora, isso (tanto quanto eu posso dizer) classifica corretamente, mas uma vez concluído, ele faz um loop indefinidamente.
Como esse código pode ser corrigido para que a função termine corretamente e classifique corretamente uma lista de qualquer tamanho (razoável)?
PS: Eu sei que realmente não deveria ter impressões em uma função e deveria ter um retorno, mas ainda não o fiz, pois meu código ainda não funciona.
python
algorithm
sorting
bubble-sort
Josh Hunt
fonte
fonte
Respostas:
Para explicar por que seu script não está funcionando no momento, vou renomear a variável
unsorted
parasorted
.No início, sua lista ainda não está classificada. É claro que começamos
sorted
aFalse
.Assim que iniciamos o
while
loop, assumimos que a lista já está classificada. A idéia é a seguinte: assim que encontrarmos dois elementos que não estão na ordem correta,sorted
voltamos aFalse
.sorted
permaneceráTrue
apenas se não houver elementos na ordem errada .Também existem pequenos problemas que ajudariam o código a ser mais eficiente ou legível.
No
for
loop, você usa a variávelelement
. Tecnicamente,element
não é um elemento; é um número que representa um índice de lista. Além disso, é bastante longo. Nesses casos, basta usar um nome de variável temporário, comoi
para "índice".O
range
comando também pode receber apenas um argumento (nomeadostop
). Nesse caso, você obtém uma lista de todos os números inteiros de 0 a esse argumento.O Guia de Estilo do Python recomenda que as variáveis sejam nomeadas em minúsculas com sublinhados. Este é um detalhe muito pequeno para um pequeno script como este; é mais para você se acostumar com o que o código Python mais se assemelha.
Para trocar os valores de duas variáveis, escreva-as como uma atribuição de tupla. O lado direito é avaliado como uma tupla (por exemplo,
(badList[i+1], badList[i])
é(3, 5)
) e, em seguida, é atribuído às duas variáveis no lado esquerdo ((badList[i], badList[i+1])
).Coloque tudo junto e você terá o seguinte:
(A propósito, também removi sua declaração impressa.)
fonte
while
loop, o maior elemento "borbulha" até o final da lista. Assim, após uma iteração, o último elemento está definitivamente no lugar certo (e não será movido por iterações sucessivas). Ao subtrair 1 do comprimento, você está otimizando o algoritmo classificando apenas a sublist que ainda não foi classificada (oslength-n
elementos mais à frente da lista). Optei por pular essa otimização, pois é mais uma otimização do que uma parte vital do algoritmo.Put it all together, and you get this:
... bem, você perdeu este:The range command can also take just one argument (named stop).
O objetivo do tipo de bolha é mover os itens mais pesados na parte inferior de cada rodada, enquanto move os itens mais leves para cima. No loop interno, onde você compara os elementos, não precisa repetir a lista inteira a cada turno . O mais pesado já está colocado por último. A variável trocada é uma verificação extra para que possamos marcar que a lista está classificada agora e evitar continuar com cálculos desnecessários.
Sua versão 1, corrigida:
fonte
Isso é o que acontece quando você usa o nome da variável com significado negativo, é necessário inverter seus valores. O seguinte seria mais fácil de entender:
Por outro lado, a lógica do algoritmo está um pouco errada. Você precisa verificar se dois elementos foram trocados durante o loop for. Aqui está como eu escreveria:
fonte
Seu uso da variável Unsorted está errado; você deseja ter uma variável que informe se você trocou dois elementos; se você tiver feito isso, poderá sair do loop, caso contrário, precisará fazer o loop novamente. Para consertar o que você tem aqui, basta colocar o "unsorted = false" no corpo do seu caso if; remova o seu caso; e coloque "unsorted = true" antes do seu
for
loop.fonte
fonte
#Uma função muito simples, pode ser otimizada (obviamente) diminuindo o espaço problemático da 2ª matriz. Mas a mesma complexidade O (n ^ 2).
fonte
arr[a], arr[b] = arr[b], arr[a]
Você tem alguns erros lá. O primeiro tem o comprimento e o segundo está no uso de itens não classificados (conforme declarado por McWafflestix). Você provavelmente também deseja retornar a lista se quiser imprimi-la:
eta: Você está certo, o acima é buggy pra caramba. Meu mal por não testar através de mais alguns exemplos.
fonte
Eu sou um novato fresco, comecei a ler sobre Python ontem. Inspirado no seu exemplo, criei algo talvez mais no estilo das 80 gravatas, mas, no entanto, meio que funciona
fonte
O problema com o algoritmo original é que, se você tivesse um número mais baixo na lista, ele não o levaria à posição correta. O programa precisa voltar no início de cada vez para garantir que os números sejam classificados por todo o caminho.
Simplifiquei o código e agora ele funcionará para qualquer lista de números, independentemente da lista e mesmo se houver números repetidos. Aqui está o código
fonte
fonte
alist = [54,26,93,17,77,31,44,55,20, -23, -34,16,11,11,11]
print bubbleSort (lista)
fonte
fonte
Um exemplo mais simples:
Isso simplesmente leva os elementos de 0 a a (basicamente, todos os elementos não classificados nessa rodada) e o compara com seu elemento adjacente e faz uma troca se for maior que seu elemento adjacente. No final da rodada, o último elemento é classificado e o processo é executado novamente sem ele, até que todos os elementos tenham sido classificados.
Não há necessidade de uma condição se
sort
verdadeira ou não.Observe que esse algoritmo leva em consideração a posição dos números somente ao trocar, portanto, números repetidos não o afetam.
PS. Sei que faz muito tempo que essa pergunta foi publicada, mas eu só queria compartilhar essa ideia.
fonte
fonte
fonte
fonte
fonte
Eu considero adicionar minha solução, porque cada solução aqui está tendo
então é deve ser
Então, aqui está a minha solução:
fonte
Se alguém estiver interessado em uma implementação mais curta usando uma compreensão de lista:
fonte
Aqui está uma variação diferente do tipo de bolha sem
for
loop. Basicamente, você está considerando olastIndex
doarray
e lentamentedecrementing
até o primeiro índice da matriz.O
algorithm
continuará a se mover pela matriz assim até que uma passagem inteira seja feita sem queswaps
ocorra.A bolha é tipo é basicamente
Quadratic Time: O(n²)
quando se trata de desempenho.fonte
As respostas fornecidas por the-fury e Martin Cote resolveram o problema do loop infinito, mas meu código ainda não funcionava corretamente (para uma lista maior, ele não seria classificado corretamente). Acabei abandonando a
unsorted
variável e usei um contador.Se alguém puder fornecer dicas sobre como melhorar meu código nos comentários, isso será muito apreciado.
fonte
Tente isto
fonte
idk se isso pode ajudá-lo após 9 anos ... é um programa simples de classificação de bolhas
fonte
fonte
fonte
fonte
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
fonte