Classificação por inserção vs. classificação por seleção

110

Estou tentando entender as diferenças entre a classificação por inserção e a classificação por seleção.

Ambos parecem ter dois componentes: uma lista não classificada e uma lista classificada. Ambos parecem pegar um elemento da lista não classificada e colocá-lo na lista classificada no lugar apropriado. Tenho visto alguns sites / livros dizendo que a classificação por seleção faz isso trocando um de cada vez, enquanto a classificação por inserção simplesmente encontra o local certo e o insere. No entanto, tenho visto outros artigos dizerem algo, dizendo que o tipo de inserção também troca. Conseqüentemente, estou confuso. Existe alguma fonte canônica?

eb80
fonte
8
A Wikipedia para ordenação por seleção vem com pseudo código e belas ilustrações, assim como a para ordenação por inserção .
G. Bach
6
@ G.Bach - obrigado por isso ... Eu li as duas páginas várias vezes, mas não entendo a diferença - daí esta questão.
eb80 de
3
De acordo com Computerphile, eles são iguais: youtube.com/watch?v=pcJHkWwjNl4
Tristan Forward

Respostas:

186

Ordenação por Seleção:

Dada uma lista, pegue o elemento atual e troque-o com o menor elemento do lado direito do elemento atual. Ordem de Seleção

Ordem de inserção:

Dada uma lista, pegue o elemento atual e insira-o na posição apropriada da lista, ajustando a lista toda vez que você inserir. É semelhante a organizar as cartas em um jogo de cartas. Ordem de inserção

A complexidade de tempo da classificação por seleção é sempre n(n - 1)/2, enquanto a classificação por inserção tem uma complexidade de tempo melhor, pois o pior caso é a complexidade n(n - 1)/2. Geralmente, serão necessárias comparações menores ou iguais n(n - 1)/2.

Fonte: http://cheetahonfire.blogspot.com/2009/05/selection-sort-vs-insertion-sort.html

Nikolay Kostov
fonte
2
@Nikolay - Isso foi apenas copiado de cheetahonfire.blogspot.com/2009/05/… que eu já li. Há algo mais preocupante, já que li artigos conflitantes.
eb80 de
5
A principal diferença é a etapa de seleção. O tipo de seleção seleciona o menor e o troca pelo primeiro. O tipo de inserção insere o atual em sua posição apropriada
Nikolay Kostov
6
@ eb80 Não tenho certeza de que material você está lendo, mas não vejo como um exemplo poderia ser mais concreto do que este.
G. Bach
23
Mas e quanto ao número de trocas? A seleção sempre faz n (n-1) / 2 comparações, mas no pior caso ela sempre fará n-1 trocas. No pior caso, a inserção fará n (n-1) / 2 comparações, bem como n (n-1) / 2 trocas.
Jason Goemaat
2
@Adorn Nenhum desses são algoritmos de divisão e conquista.
Asky McAskface
63

A classificação por inserção e a classificação por seleção têm um loop externo (sobre cada índice) e um loop interno (sobre um subconjunto de índices). Cada passagem do loop interno expande a região classificada em um elemento, às custas da região não classificada, até que fique sem elementos não classificados.

A diferença está no que o loop interno faz:

  • Na classificação de seleção, o loop interno é sobre os elementos não classificados . Cada passagem seleciona um elemento e o move para sua localização final (no final atual da região classificada).

  • Na classificação por inserção, cada passagem do loop interno itera sobre os elementos classificados . Os elementos classificados são deslocados até que o loop encontre o local correto para inserir o próximo elemento não classificado.

Portanto, em uma ordenação por seleção, os elementos classificados são encontrados na ordem de saída e permanecem assim que são encontrados. Inversamente, em uma classificação por inserção, os elementos não classificados permanecem até serem consumidos na ordem de entrada, enquanto os elementos da região classificada continuam sendo movidos.

No que diz respeito à troca: a classificação por seleção faz uma troca por passagem do loop interno. A classificação por inserção normalmente salva o elemento a ser inserido como temp antes do loop interno, deixando espaço para o loop interno deslocar os elementos classificados em um e depois copiar temppara o ponto de inserção.

tempestade que se aproxima
fonte
23

SELEÇÃO DE CLASSIFICAÇÃO
Suponha que haja uma matriz de números escrita de uma forma particular / aleatória e digamos que devemos organizar em ordem crescente ... então, pegue um número de cada vez e substitua-os pelo menor não. disponíveis na lista. realizando esta etapa, obteremos o resultado desejado.

insira a descrição da imagem aqui



TIPO DE INSERÇÃO
Tendo em mente a suposição semelhante, mas a única diferença é que desta vez estamos selecionando um número de cada vez e inserindo-o na parte pré-selecionada, o que reduziu as comparações e, portanto, é mais eficiente.

insira a descrição da imagem aqui

Akash sharma
fonte
Basta verificar o mycodeschool no Youtube. No entanto, esta resposta complementa o que é explicado nos vídeos de 2 algoritmos no youtube.
JaydeepW
21

É possível que a confusão seja porque você está comparando uma descrição de classificação de uma lista vinculada com uma descrição de classificação de uma matriz . Mas não posso ter certeza, já que você não citou suas fontes.

A maneira mais fácil de entender algoritmos de classificação é frequentemente obter uma descrição detalhada do algoritmo (não coisas vagas como "este tipo usa troca. Em algum lugar. Não estou dizendo onde"), pegue algumas cartas de jogar (5-10 deve ser suficiente para algoritmos de classificação simples) e execute o algoritmo manualmente.

Ordenação por seleção: percorra os dados não ordenados procurando o menor elemento restante e, em seguida, troque-o para a posição imediatamente após os dados ordenados. Repita até terminar. Se estiver classificando uma lista, você não precisa trocar o menor elemento para a posição; em vez disso, você pode remover o nó da lista de sua posição anterior e inseri-lo na nova.

Classificação por inserção: pegue o elemento imediatamente após os dados classificados, percorra os dados classificados para encontrar o local para colocá-los e coloque-os lá. Repita até terminar.

A classificação por inserção pode usar troca durante a fase de "varredura", mas não precisa e não é a maneira mais eficiente, a menos que você esteja classificando um array de um tipo de dados que: (a) não pode ser movido, apenas copiado ou trocado; e (b) é mais caro para copiar do que para trocar. Se a ordenação por inserção usar troca, a maneira como funciona é que você simultaneamente pesquisa o lugar e coloca o novo elemento lá, trocando repetidamente o novo elemento pelo elemento imediatamente anterior a ele, enquanto o elemento anterior for maior que isto. Depois de alcançar um elemento que não é maior, você encontrou o local correto e passa para o próximo novo elemento.

Steve Jessop
fonte
1
Isso é muito útil ... O último parágrafo mostra a confusão que eu estava tendo, que resultou das variantes de cada tipo.
eb80 de
1
+1 por observar que usar a classificação por inserção em uma lista vinculada é uma eficiência de troca completamente diferente do que com uma matriz no local
Gavin Achtemeier
11

A lógica de ambos os algoritmos é bastante semelhante. Ambos têm uma submatriz parcialmente classificada no início da matriz. A única diferença é como eles procuram o próximo elemento a ser colocado na matriz classificada.

  • Ordenação por inserção : insere o próximo elemento na posição correta;

  • Ordenação por seleção : seleciona o menor elemento e troca-o pelo item atual;

Além disso, a classificação por inserção é estável, ao contrário da classificação por seleção .

Eu implementei ambos em python, e vale a pena notar como eles são semelhantes:

def insertion(data):
    data_size = len(data)
    current = 1
    while current < data_size:
        for i in range(current):
            if data[current] < data[i]:
                temp = data[i]
                data[i] = data[current]
                data[current] = temp

        current += 1

    return data

Com uma pequena mudança é possível fazer o algoritmo de Ordenação por Seleção.

def selection(data):
    data_size = len(data)
    current = 0
    while current < data_size:
        for i in range(current, data_size):
            if data[i] < data[current]:
                temp = data[i]
                data[i] = data[current]
                data[current] = temp

        current += 1

    return data
tenda de thyago
fonte
desculpe, eu queria saber por que (algoritmo de classificação de seleção), os dados [i] são trocados com os dados [atuais] sempre que os dados [i] são menores. Na classificação de seleção básica / original (?), Encontramos o valor mínimo entre o intervalo (i, tamanho_de_dados) e trocamos dados [i] com esse valor mínimo ... isso é um pouco diferente ...
Tony Ma
4

Em suma, acho que a classificação por seleção procura o menor valor na matriz primeiro e, em seguida, faz a troca, enquanto a classificação por inserção pega um valor e o compara a cada valor restante (atrás dele). Se o valor for menor, ele troca. Em seguida, o mesmo valor é comparado novamente e se for menor ao que está atrás dele, ele troca novamente. Espero que faça sentido!

Muath
fonte
4

Em resumo,

Classificação de seleção: Selecione o primeiro elemento da matriz não classificada e compare-o com os elementos não classificados restantes. É semelhante à classificação por bolha, mas em vez de trocar cada elemento menor, mantém o índice de elemento menor atualizado e troca-o no final de cada loop .

Classificação por inserção: é o oposto da classificação por seleção, onde escolhe o primeiro elemento da submatriz não classificada e o compara com a submatriz classificada e insere o menor elemento onde foi encontrado e desloca todos os elementos classificados da direita para o primeiro elemento não classificado.

Ravi
fonte
3

Vou tentar mais uma vez: considere o que acontece no caso de sorte de uma matriz quase ordenada.

Durante a classificação, a matriz pode ser considerada como tendo duas partes: lado esquerdo - classificado, lado direito - não classificado.

Classificação por inserção - escolha primeiro o elemento não classificado e tente encontrar um lugar para ele entre a parte já classificada. Visto que você pesquisa da direita para a esquerda, pode muito bem acontecer que o primeiro elemento classificado com o qual você está comparando (o maior, mais à direita na parte esquerda) seja menor do que o elemento selecionado, de forma que você possa continuar imediatamente com o próximo elemento não classificado.

Classificação de seleção - escolha o primeiro elemento não classificado e tente encontrar o menor elemento de toda a parte não classificada, e troque os dois se desejar. O problema é que, como a peça certa está desordenada, você tem que ir pensando em cada elemento todas as vezes, já que não é possível ter certeza se existe ou não elemento menor do que o escolhido.

A propósito, isso é exatamente o que o heapsort melhora na classificação por seleção - ele é capaz de encontrar o menor elemento muito mais rapidamente por causa do heap .

Ecir Hana
fonte
3

Classificação por seleção: À medida que você começa a construir a sublista classificada, o algoritmo garante que a sublista classificada está sempre completamente classificada, não apenas em termos de seus próprios elementos, mas também em termos da matriz completa, ou seja, tanto a sublista classificada como não classificada. Assim, o novo menor elemento, uma vez encontrado na sublista não classificada, seria apenas anexado ao final da sublista classificada.

Insertion Sort: O algoritmo divide novamente o array em duas partes, mas aqui o elemento é selecionado da segunda parte e inserido na posição correta na primeira parte. Isso nunca garante que a primeira parte seja classificada em termos do array completo, embora, é claro, na passagem final cada elemento esteja em sua posição de classificação correta.

Mankadnandan
fonte
3

Ambos os algoritmos geralmente funcionam assim

Etapa 1: pegue o próximo elemento não classificado da lista não classificada e, em seguida,

Passo 2: coloque-o no lugar certo na lista classificada.

Uma das etapas é mais fácil para um algoritmo e vice-versa.

Classificação por inserção : pegamos o primeiro elemento da lista não classificada e o colocamos na lista classificada, em algum lugar . Nós sabemos onde colocar o próximo elemento (a primeira posição na lista não classificada), mas requer algum trabalho descobrir onde colocá-lo (em algum lugar ). O passo 1 é fácil.

Ordenação por seleção : pegamos o elemento em algum lugar da lista não ordenada e o colocamos na última posição da lista ordenada. Precisamos encontrar o próximo elemento (provavelmente não está na primeira posição da lista não classificada, mas em algum lugar ) e colocá-lo no final da lista classificada. O passo 2 é fácil

meu uma garantia
fonte
2

O loop interno da classificação por inserção passa por elementos já classificados (ao contrário da classificação por seleção). Isso permite que ele aborte o loop interno quando a posição correta for encontrada . O que significa que:

  1. O loop interno passará por apenas metade de seus elementos em um caso médio.
  2. O loop interno será abortado ainda mais cedo se a matriz estiver quase classificada.
  3. O loop interno abortará imediatamente se a matriz já estiver classificada, tornando a complexidade da classificação de inserção linear neste caso.

A classificação da seleção sempre terá que passar por todos os elementos do loop interno. É por isso que a classificação por inserção é mais preferida do que a classificação por seleção. Mas, por outro lado, o tipo de seleção faz muito menos trocas de elementos, o que pode ser mais importante em alguns casos.

Danila Piatov
fonte
1

Basicamente, a classificação por inserção funciona comparando dois elementos por vez e a classificação por seleção seleciona o elemento mínimo de todo o array e o classifica.

A classificação por inserção conceitualmente continua classificando a sub-lista comparando dois elementos até que todo o array seja classificado, enquanto a classificação por seleção seleciona o elemento mínimo e o troca para a primeira posição, o segundo elemento mínimo para a segunda posição e assim por diante.

A classificação de inserção pode ser mostrada como:

    for(i=1;i<n;i++)
        for(j=i;j>0;j--)
            if(arr[j]<arr[j-1])
                temp=arr[j];
                arr[j]=arr[j-1];
                arr[j-1]=temp;

A classificação da seleção pode ser mostrada como:

    for(i=0;i<n;i++)
        min=i;
        for(j=i+1;j<n;j++)
        if(arr[j]<arr[min])
        min=j;
        temp=arr[i];
        arr[i]=arr[min];
        arr[min]=temp;
Pankti
fonte
1

A escolha desses 2 algoritmos de classificação se resume à estrutura de dados usada.

Quando você estiver usando arrays, use a classificação por seleção (embora por que, quando você pode usar qsort?). Quando você estiver usando listas vinculadas, use a classificação por inserção.

Isto é porque:

  • A travessia de listas vinculadas é mais cara do que matrizes.
  • A inserção de lista vinculada é muito mais barata do que arrays.

A classificação por inserção injeta o novo valor no meio do segmento classificado. Portanto, os dados precisam ser "empurrados". No entanto, quando você está usando uma lista vinculada, torcendo 2 ponteiros, você efetivamente empurrou a lista inteira para trás. Em uma matriz, você deve realizar n - i swaps para empurrar os valores de volta, o que pode ser muito caro.

A classificação de seleção sempre acrescenta ao final, portanto, não há esse problema ao usar matrizes. Portanto, os dados não precisam ser "empurrados".

John
fonte
0

Uma explicação simples poderia ser a seguinte:

Dado : Um array não classificado ou lista de números.

Declaração do problema : para classificar a lista / matriz de números em ordem crescente para entender a diferença entre a classificação por seleção e a classificação por inserção.

Ordem de inserção:Você vê a lista de cima para baixo para facilitar a compreensão. Consideramos o primeiro elemento como nosso valor mínimo inicial. Agora, a ideia é percorrermos cada índice dessa lista / array linearmente para descobrir se há algum outro elemento em qualquer índice que esteja tendo um valor menor do que o valor mínimo inicial. Se encontrarmos esse valor, apenas trocamos os valores em seus índices, ou seja, digamos que 15 foi o valor inicial mínimo no índice 1 e durante a travessia linear dos índices, encontramos um número com menor valor, digamos 7 no índice 9 Agora, este valor 7 no índice 9 é trocado com o índice 1 tendo 15 como seu valor. Esta travessia continuará a fazer comparação com o valor do índice atual com os índices restantes para trocar pelo valor menor. Isso continua até o penúltimo índice da lista / matriz,

Ordenação por Seleção:Vamos supor que o primeiro elemento de índice da lista / matriz seja classificado. Agora, do elemento no segundo índice, nós o comparamos com seu índice anterior para ver se o valor é menor. O percurso pode ser visualizado em duas partes, classificadas e não classificadas. Seria possível visualizar uma verificação de comparação do não classificado para o classificado para um determinado índice na lista / array. Digamos que você tenha o valor 19 no índice 1 e o valor 10 no índice 3. Consideramos a travessia do não classificado para o classificado, ou seja, da direita para a esquerda. Então, digamos que temos que classificar no índice 3. Vemos que ele tem um valor menor do que o índice 1 quando comparamos da direita para a esquerda. Uma vez identificado, apenas colocamos este número 10 do índice 3 no lugar do índice 1 tendo o valor 19. O valor original 19 no índice 1 é deslocado um lugar para a direita.

Não adicionei nenhum código, pois parece que a questão é entender o conceito do método de travessia.

Sid
fonte
0

A classificação por inserção não troca coisas. Mesmo que faça uso de uma variável temporária, o objetivo de fazer uso de uma variável temporária é quando descobrimos que um valor em um índice é menor em comparação com o valor de seu índice anterior, deslocamos o valor maior para o local do menor valor índice que sobrescreveria as coisas. Em seguida, usamos a var temp para ser substituída no índice anterior. Exemplo: 10, 20, 30, 50, 40. iteração 1: 10, 20, 30, 50, 50. [temp = 40] iteração 2: 10,20, 30, 40 (valor do temp), 50. Então, nós basta inserir um valor na posição desejada de alguma variável.

Mas quando consideramos a ordenação por seleção, primeiro encontramos o índice com valor inferior e trocamos esse valor pelo valor do primeiro índice e continuamos trocando repetidamente até que todos os índices sejam classificados. Isso é exatamente igual à troca tradicional de dois números. Exemplo: 30, 20, 10, 40, 50. Iteração 1: 10, 20, 30, 40, 50. Aqui, temp var é usado exclusivamente para troca.

AravindKumar Chilakamarri
fonte
0

A classificação por inserção faz muito mais troca dessa seleção. Aqui está um exemplo:

insira a descrição da imagem aqui

user4617883
fonte
0

O que ambos têm em comum é que ambos usam uma partição para diferenciar entre a parte classificada da matriz e a não classificada.

A diferença é que, com a classificação de seleção, você tem a garantia de que a parte classificada do array não mudará ao adicionar elementos à partição classificada.

A razão é que a seleção procura o mínimo do conjunto não classificado e o adiciona logo após o último elemento do conjunto classificado, aumentando assim o conjunto classificado em 1.

A inserção, por outro lado, só se preocupa com o próximo elemento encontrado, que é o primeiro elemento na parte não classificada da matriz. Ele pegará esse elemento e simplesmente o ajustará em seu devido lugar no conjunto classificado.

A classificação por inserção normalmente sempre será um candidato melhor para matrizes que são classificadas apenas parcialmente porque você está desperdiçando operações para encontrar o mínimo.

Conclusão:

A classificação por seleção adiciona um elemento ao final, encontrando o elemento mínimo na seção não classificada.

A classificação por inserção propaga o primeiro elemento encontrado na seção não classificada para qualquer lugar da seção classificada.

Moshe Rabaev
fonte
0

Embora a complexidade de tempo de classificação de seleção e classificação de inserção seja a mesma, isto é, n (n - 1) / 2. A classificação de inserção de desempenho médio é melhor. Testado em minha cpu i5 com 30000 inteiros aleatórios, a classificação por seleção levou 1,5 s em média, enquanto a classificação por inserção levou 0,6 s em média.

Gostar
fonte
Bem-vindo ao StackOverflow e obrigado pela resposta. Provavelmente, você pode ver que muitas pessoas já contribuíram com boas respostas com ilustrações visuais. Por exemplo, Nikolay Kostov, 7 anos atrás, afirmou que a complexidade do tempo é a mesma apenas no pior caso para o tipo de inserção. Se você acha que ele está errado, convidamos você a expandir sua resposta com mais detalhes.
Maxim Sagaydachny
-1

Em termos leigos (e provavelmente a maneira mais fácil de obter um entendimento de alto nível do problema)

A classificação por bolha é semelhante a ficar em uma linha e tentar se classificar por altura. Você continua trocando com a pessoa ao seu lado até estar no lugar certo. Isso ocorre da esquerda para a direita (ou direita, dependendo da implementação) e você continua alternando até que todos estejam classificados.

Na classificação por seleção, no entanto, o que você está fazendo é semelhante a organizar uma mão de cartas. Você olha as cartas, pega a menor, coloca-a totalmente à esquerda e assim por diante.

Harsh G.
fonte
3
Ele está perguntando sobre a diferença entre a classificação por Seleção e por Inserção
XuDing
-1

seleção - selecionar um item específico (o mais baixo) e trocá-lo pelo i (número de iteração) o elemento. (ou seja, primeiro, segundo, terceiro .......), portanto, fazendo a lista classificada de um lado.

inserção - comparando primeiro com segundo compare terceiro com segundo e primeiro compare quarto com terceiro, segundo e primeiro ......

um link onde todas as classificações são comparadas

nikhil2000
fonte