Estou tentando entender alguns algoritmos de classificação, mas estou lutando para ver a diferença na classificação por bolha e no algoritmo de classificação por inserção.
Eu sei que ambos são O (n 2 ), mas me parece que a classificação por bolha apenas borbulha o valor máximo da matriz para o topo de cada passagem, enquanto a classificação por inserção apenas afunda o valor mais baixo para baixo a cada passagem. Eles não estão fazendo exatamente a mesma coisa, mas em direções diferentes?
Para classificação por inserção, o número de comparações / trocas potenciais começa em zero e aumenta a cada vez (ou seja, 0, 1, 2, 3, 4, ..., n), mas para classificação por bolha esse mesmo comportamento acontece, mas no final de a classificação (ou seja, n, n-1, n-2, ... 0) porque a classificação por bolha não precisa mais ser comparada com os últimos elementos à medida que são classificados.
Por tudo isso, porém, parece um consenso que o tipo de inserção é melhor em geral. Alguém pode me dizer o porquê?
Edit: Estou interessado principalmente nas diferenças em como os algoritmos funcionam, não tanto em sua eficiência ou complexidade assintótica.
Respostas:
Na ordenação por bolha na iª iteração, você tem ni-1 iterações internas (n ^ 2) / 2 no total, mas na ordenação por inserção você tem no máximo i iterações na i'ésima etapa, mas i / 2 em média, já que você pode parar o loop interno antes, depois de encontrar a posição correta para o elemento atual. Então você tem (soma de 0 an) / 2 que é (n ^ 2) / 4 total;
É por isso que a classificação por inserção é mais rápida do que a classificação por bolha.
fonte
Ordem de inserção
Após i iterações, os primeiros i elementos são ordenados.
Em cada iteração, o próximo elemento é borbulhado pela seção classificada até chegar ao ponto certo:
sorted | unsorted 1 3 5 8 | 4 6 7 9 2 1 3 4 5 8 | 6 7 9 2
O 4 é borbulhado na seção classificada
Pseudo-código:
for i in 1 to n for j in i downto 2 if array[j - 1] > array[j] swap(array[j - 1], array[j]) else break
Tipo de bolha
Após i iterações, os últimos i elementos são os maiores e ordenados.
Em cada iteração, examine a seção não classificada para encontrar o máximo.
O 5 é borbulhado da seção não classificada
Pseudo-código:
for i in 1 to n for j in 1 to n - i if array[j] > array[j + 1] swap(array[j], array[j + 1])
Observe que as implementações típicas terminam mais cedo se nenhuma troca for feita durante uma das iterações do loop externo (já que isso significa que a matriz está classificada).
Diferença
Na classificação por inserção, os elementos são borbulhados na seção classificada, enquanto na classificação por bolha os máximos são borbulhados para fora da seção não classificada.
fonte
Outra diferença, não vi aqui:
A classificação por bolha tem 3 atribuições de valor por troca : você deve construir uma variável temporária primeiro para salvar o valor que deseja empurrar para a frente (nº 1), e depois escrever a outra variável de troca no local em que acabou de salvar o valor de (nº 2) e então você tem que escrever sua variável temporária no outro local (nº 3). Você tem que fazer isso para cada local - você deseja avançar - para classificar sua variável no local correto.
Com a ordenação por inserção, você coloca sua variável para ordenar em uma variável temporária e, em seguida, coloca todas as variáveis na frente daquele ponto 1 ponto para trás, contanto que você alcance o ponto correto para sua variável. Isso perfaz 1 atribuição de valor por local . No final, você escreve sua variável temporária no local.
Isso faz com que atribuições de valor muito menos também.
Este não é o maior benefício de velocidade, mas acho que pode ser mencionado.
Espero, me expressei compreensível, se não, desculpe, não sou um nativo da Grã-Bretanha
fonte
A principal vantagem da classificação por inserção é que é um algoritmo online. Você não precisa ter todos os valores no início. Isso pode ser útil ao lidar com dados vindos da rede ou de algum sensor.
Tenho a sensação de que isso seria mais rápido do que outros
n log(n)
algoritmos convencionais . Porque a complexidade seria,n*(n log(n))
por exemplo, ler / armazenar cada valor de stream (O(n)
) e, em seguida, classificar todos os valores (O(n log(n))
) resultando emO(n^2 log(n))
Ao contrário, usar Insert Sort precisa
O(n)
ler os valores do stream eO(n)
colocar o valor no lugar correto, portanto, é oO(n^2)
único. Outra vantagem é que você não precisa de buffers para armazenar valores, você os classifica no destino final.fonte
O(n log(n))
um trabalho total executado para ter uma coleção classificada em cada etapa do caminho. (Um percurso em ordem em qualquer ponto éO(m)
). Se você só precisa de um resultado classificado no final, mas deseja sobrepor o cálculo de classificação com o tempo de transferência dos dados, um heap pode ser bom. (E funciona no local, como classificação por inserção).O(f(n))
classe de complexidade importe mais do que detalhes de implementação e fatores constantes.n
inserções, então realmente se resume a qual algoritmo é melhor para ordenar um array quase ordenado onde há um elemento não ordenado no topo. MuitosO(n log(n))
algoritmos de classificação estãoO(n)
no caso quase classificado, então não é verdade que você precisesum(M=1..n, O(M * log(M)) )
trabalhar. Isso realmente seriaO(n^2 log(n))
, mas com a escolha certa do algoritmo, eles serãoO(n^2)
um trabalho total. A classificação por inserção é a mais eficiente para isso.O Bubble Sort não está online (ele não pode classificar um fluxo de entradas sem saber quantos itens haverá) porque ele realmente não mantém o controle de um máximo global dos elementos classificados. Quando um item for inserido, você precisará começar a borbulhar desde o início
fonte
bem a classificação por bolha é melhor do que a classificação por inserção apenas quando alguém está procurando os k principais elementos de uma grande lista de números, ou seja, na classificação por bolha após k iterações você obterá os k principais elementos. No entanto, após k iterações na classificação por inserção, isso apenas garante que esses k elementos sejam classificados.
fonte
Embora ambas as classificações sejam O (N ^ 2). As constantes ocultas são muito menores na classificação por inserção. As constantes ocultas referem-se ao número real de operações primitivas realizadas.
Quando a classificação por inserção tem melhor tempo de execução?
Observe que a classificação por inserção nem sempre é melhor do que a classificação por bolha. Para obter o melhor dos dois mundos, você pode usar a classificação por inserção se o array for pequeno e, provavelmente, mesclar classificação (ou quicksort) para arrays maiores.
fonte
Número de troca em cada iteração
Acessando e alterando a parte classificada
Online ou não
adjacent-inputs
.adjacent-inputs
em cada iteração.fonte
A classificação por bolha é quase inútil em todas as circunstâncias. Em casos de uso, quando a classificação por inserção pode ter muitas trocas, a classificação por seleção pode ser usada porque garante menos de N vezes de troca. Como a classificação por seleção é melhor do que a classificação por bolha, a classificação por bolha não tem casos de uso.
fonte
classificação de inserção:
1.Na troca de classificação de inserção não é necessária.
2. a complexidade de tempo da classificação por inserção é Ω (n) para o melhor caso e O (n ^ 2) para o pior caso.
3. menos complexo em comparação com o tipo de bolha.
4.exemplo: insira livros na biblioteca, organize os cartões.
tipo de bolha: 1.Swapping necessário no tipo de bolha.
2. a complexidade de tempo da classificação por bolha é Ω (n) para o melhor caso e O (n ^ 2) para o pior caso.
3.mais complexo em comparação com o tipo de inserção.
fonte
A ordenação por inserção pode ser resumida como " Procure o elemento que deve estar na primeira posição (o mínimo), crie algum espaço deslocando os próximos elementos e coloque-o na primeira posição. Bom. Agora, olhe para o elemento que deve estar na 2ª posição. ... "e assim por diante ...
A classificação por bolha opera de maneira diferente, o que pode ser resumido como " Contanto que eu encontre dois elementos adjacentes que estejam na ordem errada, eu os troco ".
fonte