## ShellSort

Este algoritmo é batizado em homenagem ao autor dele, Donald Shell, que o publicou em 1959. Seja uma aplicação da ideia do CombSort (faz com que elementos que tem um longo caminho tomarem atalhos) ao insertion sort (CombSort é uma variação do BubbleSort). Ao invés de comparar valores adjacentes durante o insertion sort, compara valores separados por um intervalo maior. Quanto maior o intervalo, mais rápido os elementos se movem ao destino deles, mas também menos preciso fica o movimento. É, portanto, essencial que o algoritmo vá a ser aplicado numa série de intervalos cada vez menor. No último passo, quando o intervalo for 1, o InsertionSort será usado, mas numa array que estará praticamente ordenada pelos passos anteriores.

Donald Shell propôs `len/2` como o valor inicial do intervalo e ir a dividir por 2 a cada passo. O pseudo-código é o seguinte:

    gap=len/2
    while gap>0:
      apply InsertionSort, comparing i-gap and i, then i-2gap and i-gap, then i-3gap and i-2gap, etc.

Assim como no CombSort, a sequência de valores levados pelo intervalo é crucial para o desempenho do Shell sort. Em alguns casos patológicos raros, a sequência que usamos pode levar a um desempenho O(n^2). Outras sequências foram propostas: os incrementos de Hibbard de 2k − 1 levam a uma complexidade de O(n^(3/2)) em casos ruins. Incrementos de Pratt 2^i3^j levam a um desempenho de O(nlog(n)log(n) nos piores casos. A existência de uma sequência a levar a O(n log(n)) foi excluída por Poonen, Plaxton e Suel. Graças a este desempenho, ShellSort é um candidato válido para arrays de várias centenas de milhares quando corretamente implementado.

No nosso caso, a array é pequena demais para se beneficiar destas otimizações. Se ainda assim quiser, tome o intervalo inicial como o maior valor da série alvo ainda menor que o tamanho do array e depois use valores decrescentes da série.

Um fato interessante: Determinar a melhor sequência de intervalos para o shell sort se tornou um tema de pesquisa de nosso século em ciência da computação. Por exemplo, um artigo de 2001 introduz a seguinte sequência, que parece ser a melhor na prática para arrays de tamanho até 10^5: {1, 4, 10, 23, 57, 132, 301, 701, 1750} (Marcin Ciura, Best Increments for the Average Case of Shellsort, 13th International Symposium on Fundamentals of Computation Theory, LNCS 2001; Vol. 2138).