Algoritmo de classificação de shell com EXEMPLO
O que é classificação de shell
O método Shell, ou classificação Shell na estrutura de dados, é um algoritmo eficiente de classificação por comparação no local. Seu nome é uma homenagem a Donald Shell quando ele propôs a ideia inicial em 1959. Shell sort é uma extensão generalizada do algoritmo de classificação por inserção.
A ideia fundamental deste algoritmo de classificação é agrupar os elementos que estão distantes e classificá-los de acordo. Em seguida, diminua gradualmente a distância entre eles. A classificação Shell supera a complexidade média do tempo de caso da classificação por inserção, comparando e trocando elementos que estão distantes.
Essa lacuna, conhecida como intervalo, é reduzida de acordo com algumas sequências de lacunas ótimas. O tempo de execução do shell sort também depende dessas sequências. Existem várias sequências de lacunas, como a sequência original de Shell, a fórmula de Knuth, os incrementos de Hibbard, etc. A sequência de lacunas original de Shell é - n/2, n/4, n/8, ……….1
Algoritmo de classificação de shell
As etapas ou procedimentos para o algoritmo de classificação de shell são as seguintes:
Passo 1) Inicialize o valor do intervalo, h = n/2. (Neste exemplo, n é o tamanho da matriz)
Passo 2) Coloque todos os elementos a uma distância do intervalo h em uma sublista.
Passo 3) Classifique essas sublistas usando classificação por inserção.
Passo 4) Defina o novo intervalo, h=h/2.
Passo 5) Se h>0, vá para a etapa 2. Caso contrário, vá para a etapa 6.
Passo 6) A saída resultante será a matriz classificada.
Como funciona a classificação de shell
Na classificação por inserção, os elementos são movidos apenas uma posição por vez. Pelo contrário, o shell sort divide o array em partes menores com base no valor do intervalo e executa a classificação por inserção nessas partes.
Gradualmente, o valor do intervalo diminui e o tamanho das peças divididas aumenta. Como as peças são classificadas individualmente de antemão, a fusão dessas peças requer menos etapas do que a tipo de inserção.
O GIF a seguir mostra uma demonstração de classificação de shell. Nesta demonstração, os valores indicados em vermelho e azul são comparados e trocados com base na classificação por inserção. Em seguida, o intervalo diminui e a classificação do shell inicia a classificação por inserção nos dados quase classificados.
Funcionamento do algoritmo de classificação Shell
Vejamos o seguinte exemplo de algoritmo de classificação de shell. Neste exemplo, classificaremos o seguinte array usando shell sort:
Passo 1) Aqui, o tamanho do array é 8. Assim, o valor do intervalo será h = 8/2 ou 4.
Passo 2) Agora, armazenaremos todos os elementos a uma distância de 4. Para o nosso caso, as sublistas são- {8, 1}, {6, 4}, {7, 5}, {2, 3}.
Passo 3) Agora, essas sublistas serão classificadas usando classificação por inserção, onde uma variável temporária é usada para comparar os dois números e classificar de acordo.
A matriz seria semelhante à seguinte após a troca de operações-
Passo 4) Agora diminuiremos o valor inicial do intervalo. O novo intervalo será h=h/2 ou 4/2 ou 2.
Passo 5) Como 2>0, iremos para a etapa 2 para armazenar todos os elementos a uma distância de 2. Por enquanto, as sublistas são-
{1, 5, 8, 7}, {4, 2, 6, 3}
Em seguida, essas sublistas serão classificadas usando classificação por inserção. Depois de comparar e trocar a primeira sublista, o array seria o seguinte.
Após classificar a segunda sublista, o array original será:
Então, novamente, o intervalo será diminuído. Agora o intervalo será h=h/2 ou 2/1 ou 1. Portanto, usaremos o algoritmo de classificação por inserção para classificar o array modificado.
A seguir está a descrição do procedimento passo a passo da classificação por inserção.
O intervalo é novamente dividido por 2. Nesse momento, o intervalo se torna 0. Então, vamos para a etapa 6.
Passo 6) Como o intervalo é 0, o array é classificado neste momento. A matriz classificada é-
Pseudo-código
Start Input array an of size n for (interval = n / 2; interval & gt; 0; interval /= 2) for (i = interval; i & lt; n; i += 1) temp = a[i]; for (j = i; j & gt; = interval & amp; & amp; a[j - interval] & gt; temp; j -= interval) a[j] = a[j - interval]; a[j] = temp; End
Programa de classificação de shell em C/C++
Entrada:
//Shell Sort Program in C/C++ #include <bits/stdc++.h> using namespace std; void ShellSort(int data[], int size) { for (int interval = size / 2; interval > 0; interval /= 2) { for (int i = interval; i < size; i += 1) { int temp = data[i]; int j; for (j = i; j >= interval && data[j - interval] > temp; j -= interval) { data[j] = data[j - interval]; } data[j] = temp; } } } int main() { int data[] = {8, 6, 7, 2, 1, 4, 5, 3}; int size = sizeof(data) / sizeof(data[0]); ShellSort(data, size); cout << "Sorted Output: \n"; for (int i = 0; i < size; i++) cout << data[i] << " "; cout << "\n"; }
Saída:
Sorted Output: 1 2 3 4 5 6 7 8
Exemplo de classificação de shell em Python
Entrada:
#Shell Sort Example in Python def ShellSort(data, size): interval = size // 2 while interval > 0: for i in range(interval, size): temp = data[i] j = i while j >= interval and data[j - interval] > temp: data[j] = data[j - interval] j -= interval data[j] = temp interval //= 2 data = [8, 6, 7, 2, 1, 4, 5, 3] ShellSort(data, len(data)) print('Sorted Output:') print(data)
Saída:
Sorted Output: [1, 2, 3, 4, 5, 6, 7, 8]
Aplicações de Shell Sort
Aqui estão aplicações importantes do Shell Sort:
- A classificação Shell é usada no Kernel do Linux porque não usa uma pilha de chamadas.
- A biblioteca uClibc usa classificação Shell.
- O compressor bzip2 usa classificação Shell para parar de exceder a recursão.
Vantagens e desvantagens do tipo Shell
Diferenciais | Desvantagens |
---|---|
Nenhuma chamada de pilha é necessária. | Não é eficiente para tamanhos de array enormes. |
Fácil implementação. | Ineficiente para elementos amplamente espalhados. |
Eficiente para elementos menos espaçados. |
Análise de complexidade de classificação de shell
Complexidade de tempo do Shell Sort
A complexidade de tempo do algoritmo de classificação de shell é O (n ^ 2). O raciocínio é o seguinte:
Para o melhor cenário, a quantidade total de testes para todos os intervalos quando a matriz foi previamente organizada é igual ao log n. Assim, a complexidade seria O(n*log n).
Para o pior cenário, vamos considerar que o array consiste de tal forma que os elementos requerem o maior número de comparações. Então, todos os elementos não serão comparados e trocados até a última iteração. Portanto, o total de comparações necessárias para o incremento final é O(n^2).
Em conclusão, as complexidades de tempo seriam
- Melhor complexidade do caso: O(n*log n)
- Complexidade média do caso: O(n*log n)
- Complexidade de pior caso: O (n ^ 2)
A complexidade do tempo de execução da classificação de shell depende muito das sequências de incremento de intervalo usadas. No entanto, a melhor sequência de incremento para classificação de shell ainda é desconhecida.
Complexidade do espaço de classificação de shell
Nesta classificação de comparação, não precisamos de nenhum espaço auxiliar adicional. Assim, a complexidade espacial deste tipo de algoritmo é O(1).