# InsertionSort

Este algoritmo de ordenação é muito simples de entender e escrever, mesmo se não for o mais eficiente possível. A complexidade assintótica dela é O(n2), mas é mais eficiente, na prática (linear no melhor caso, p.ex. quando a array já está ordenada e N2/4 no caso médio).

A ideia é percorrer todos os elementos da array e inserir cada um deles na posição correta dele numa parte já ordenada da array. Quando olhamos num elemento x, a situação é a seguinte: qualquer elemento da esquerda da array já está ordenado e temos que inserir x na posição dele na array.

Uma vez isto feito, a situação é a seguinte:

O pseudo-código deste algoritmo é então o seguinte:

    For each i in [1,len-1]
      store the value of i in a variable v
      copy the cell i-1 into i if i-1 contains a value bigger than v
      copy the cell i-2 into i-1 if i-2 contains a value bigger than v
      copy the cell i-3 into i-2 if i-3 contains a value bigger than v
      copy the cell i-4 into i-3 if i-4 contains a value bigger than v
      ...
      copy v into the last cell copied above

Naturalmente, deve usar um loop para escrever a grande permutação dentro do loop. Escrever ela desta forma deve ser na verdade ... improdutivo.

Se já se perguntou o que cientistas da computação fazem nos dias de hoje, aqui está uma parte da resposta: Eles melhoram algoritmos fundamentais para que outras pessoas possam escrever programas eficientes.

## Outra variação do insertion sort

TreeSort constrói uma árvore de busca binária para ordená-la. Consegue O(n log(n)) no caso médio, mas O(n^2) nos piores casos. Não vamos estudar este algoritmo aqui, pois para entendê-lo temos que entender o que uma árvore binária é, o que está além dos nossos objetivos atuais.

Existem variações do insertion sort, tais como o PatienceSort que constrói pilhas de valores e ordena cada pilha depois. Este algoritmo apresenta um tempo 0(n log(n)) no pior caso e uma complexidade de espaço de 0(n). LibrarySort (proposto em 2004) também troca um pouco de espaço por tempo já que tem uma complexidade de tempo de O(n log(n)) mas precisa armazenar um pouco mais de dados.

A Wikipédia fornece uma descrição detalhada de cada um destes algoritmos que não apresentamos aqui devido a limitações de tempo.