Ordenação de valores e registros

Ordenação: elementos, chaves e critérios

Ordenar significa reorganizar os mesmos elementos segundo uma ordem predeterminada. A sequência final deve estar ordenada e continuar sendo uma permutação da entrada.

comparar · mover · ordenar

O que realmente é comparado?

Quando os elementos são números, o próprio valor pode ser a chave. Quando são objetos, escolhemos um ou mais campos.

  • Elemento: o registro completo que será movido.
  • Chave: informação usada para decidir a posição.
  • Critério: crescente, decrescente ou combinação de campos.

Propriedades importantes

  • Estável: preserva a ordem original entre elementos com chaves iguais.
  • In-place: usa pouca memória auxiliar além da própria coleção.
  • Adaptativo: aproveita alguma ordem já existente na entrada.
  • Por comparação: decide a ordem comparando pares de chaves.

Visualização passo a passo

Escolha um algoritmo e acompanhe comparações, trocas e a região que já chegou à posição definitiva ou ordenada.

Algoritmos elementares

Estado

A animação do Insertion Sort usa trocas entre vizinhos para deixar o movimento visível. A implementação em C++ mais abaixo produz a mesma ordenação usando deslocamentos.

Como cada algoritmo organiza os valores

AlgoritmoIdeia centralPonto de atenção
Insertion SortMantém um prefixo ordenado e insere nele o próximo valor.É eficiente para entradas pequenas ou quase ordenadas.
Selection SortProcura o menor valor restante e o coloca na próxima posição.Faz Θ(n²) comparações mesmo se a entrada já estiver ordenada.
Bubble SortCompara vizinhos e troca os pares invertidos; os maiores avançam para o fim.A versão otimizada encerra quando uma passagem não faz trocas.
Merge SortDivide a sequência, ordena as metades e intercala duas partes já ordenadas.Em arrays, normalmente precisa de memória auxiliar proporcional a n.
QuicksortEscolhe um pivô e particiona os valores em torno dele antes das chamadas recursivas.A qualidade das partições determina se o comportamento fica próximo de n log n ou chega a n².
Counting SortConta quantas vezes cada chave inteira ocorre e reconstrói a saída.É apropriado quando o intervalo de chaves k é conhecido e não é excessivamente grande.

Comparação dos métodos

AlgoritmoMelhor casoMédio / típicoPior casoEspaço auxiliar típicoEstável?
Insertion SortO(n)O(n²)O(n²)O(1)Sim
Selection SortO(n²)O(n²)O(n²)O(1)Não, na forma usual
Bubble Sort otimizadoO(n)O(n²)O(n²)O(1)Sim
Merge Sort em arrayΘ(n log n)Θ(n log n)Θ(n log n)O(n)Sim, na forma usual
QuicksortO(n log n)O(n log n)Θ(n²)O(log n) típico; O(n) no pior caso pela recursãoNão, na forma usual
Counting SortO(n + k)O(n + k)O(n + k)O(k), ou O(n + k) na versão estávelPode ser

k é a quantidade de chaves possíveis ou o tamanho do intervalo considerado. Counting Sort não é um algoritmo geral de comparação.

Insertion Sort em C++

A parte à esquerda de i permanece ordenada. O elemento atual é deslocado até encontrar sua posição.

C++17implementação didática
#include <vector>

void insertion_sort(std::vector<int>& valores) {
    for (int i = 1; i < static_cast<int>(valores.size()); ++i) {
        int chave = valores[i];
        int j = i - 1;

        while (j >= 0 && valores[j] > chave) {
            valores[j + 1] = valores[j];
            --j;
        }

        valores[j + 1] = chave;
    }
}

Ordenando objetos por vários campos

A função key transforma cada objeto em uma chave. Tuplas são comparadas campo a campo, da esquerda para a direita.

C++17struct + comparador
#include <string>

struct Produto {
    int codigo;
    std::string nome;
    double preco;
};

bool por_preco(const Produto& a, const Produto& b) {
    return a.preco < b.preco;
}

// Uso:
// std::sort(produtos.begin(), produtos.end(), por_preco);

sort() ou stable_sort()?

RecursoResultadoEntrada aceita
std::sortOrdena o intervalo no próprio contêiner.Não preserva necessariamente a ordem dos equivalentes.
std::stable_sortOrdena preservando a ordem relativa dos equivalentes.Exige memória auxiliar.

Em C++, escolha std::stable_sort quando objetos com a mesma chave precisarem manter sua ordem relativa original.

Biblioteca não significa um algoritmo único: a implementação de std::sort pode combinar técnicas, desde que cumpra as garantias de complexidade do padrão.

Sobre o material-base enviado

A aula apresenta Insertion, Selection, Bubble, Merge, Quicksort, Counting Sort e critérios customizados. As complexidades foram revisadas com as definições do NIST e a documentação oficial da linguagem.