Ordenar sem Comparar: Contagem, Radix e a Escolha da Ferramenta
por Frank de Alcantara em 01/10/2026
- 1. Contar Antes de Programar: Complexidade, Restrições e Medição
- 2. A Máquina por Baixo do Algoritmo: Tipos, Cache e Desvios
- 3. Treino T01: Contando Antes de Codificar
- 4. Caixa de Ferramentas I: Tipos, Números e Trabalho em Tempo de Compilação
- 5. Caixa de Ferramentas II: Vetores, Matrizes, Vistas e Algoritmos
- 6. Treino T02: Pagar Uma Vez, Perguntar Sempre
- 7. Entrada e Saída de Alto Desempenho
- 8. Treino T03: Alimentando a Máquina
- 9. Busca Binária: Comprar Informação pela Metade
- 10. Ordenar por Comparação: o Limite, a Biblioteca e a Seleção
- 11. Ordenar sem Comparar: Contagem, Radix e a Escolha da Ferramenta
- 12. Treino T04: Comprar Informação
- 13. Somas de Prefixo e Arrays de Diferenças: Integrar e Derivar em Tempo Constante
- 14. Janelas que Deslizam: Deque Monotônico, Dois Ponteiros, Kadane e Sparse Table
- 15. Bits como Conjuntos: Máscaras, popcount e Bitsets de Muitas Palavras
- 16. Hash de Prefixo, Seleção em Três Partes e o Algoritmo de Mo
- 17. Treino T05: Intervalos com Orçamento
- 18. Pilhas, Filas, Heaps e Contêineres Associativos: o Estado que Sobrevive à Pergunta Seguinte
O Artigo 10 terminou com um piso: nenhum algoritmo que só compara elementos ordena
O piso vale para quem só pergunta
As medições foram feitas com o MSVC do Visual Studio 18.10.3, com /std:c++latest /O2, em um Intel Core i7-10750H. Cada tempo é a mediana de cinco execuções depois de uma de aquecimento, e cada execução recebe uma cópia nova dos dados, feita fora do cronômetro. Os programas deste artigo, com as entradas e as saídas esperadas de cada caso de teste, estão em serie-blog/competitiva-11.
1. A informação que a comparação não usa
Vamos começar pelo caso mais favorável. Os valores são inteiros em um intervalo pequeno e conhecido,
1
2
3
4
5
6
vetor: 4 1 3 1 0 4 1
contagem: valor 0 aparece 1 vez
valor 1 aparece 3 vezes
valor 2 aparece 0 vezes
valor 3 aparece 1 vez
valor 4 aparece 2 vezes
Com a tabela de contagens pronta, a ordenação é só reescrever cada valor tantas vezes quantas ele apareceu, do menor para o maior:
1
2
3
4
5
6
7
8
9
10
11
std::vector<int> contagem_simples(const std::vector<int>& a, int k) {
std::vector<int> cont(k, 0);
for (int x : a) ++cont[x]; // n incrementos
std::vector<int> saida;
saida.reserve(a.size());
for (int valor = 0; valor < k; ++valor) // k contadores visitados
for (int c = 0; c < cont[valor]; ++c)
saida.push_back(valor);
return saida;
}
Este artigo completo contém estratégias práticas e dados exclusivos reservados para nossos membros cadastrados.
Continuar com Google Acesso gratuito e instantâneo com sua conta Google(Updated: )