Como Ordenar Vetor em Rust

Aprenda a ordenar vetores em Rust com sort(), sort_by(), sort_by_key(), sort_unstable() e reverse(). Exemplos completos com structs e critérios customizados.

Ordenar dados é uma das operações mais comuns em programação. Rust oferece métodos de ordenação eficientes diretamente nos slices e vetores, com suporte a critérios customizados e ordenação estável ou instável. Nesta receita, você vai dominar todas as formas de ordenar dados em Rust.

Dependências

Todos os métodos de ordenação fazem parte da biblioteca padrão:

[package]
name = "receita-ordenar"
version = "0.1.0"
edition = "2021"

Código Completo

fn main() {
    // =============================================
    // 1. sort() — ordenação simples (estável)
    // =============================================
    let mut numeros = vec![5, 2, 8, 1, 9, 3, 7, 4, 6];
    numeros.sort();
    println!("sort():           {:?}", numeros);
    // [1, 2, 3, 4, 5, 6, 7, 8, 9]

    // Ordenar strings (ordem lexicográfica/alfabética)
    let mut frutas = vec!["banana", "abacaxi", "manga", "cereja", "damasco"];
    frutas.sort();
    println!("Frutas ordenadas: {:?}", frutas);
    // ["abacaxi", "banana", "cereja", "damasco", "manga"]

    // =============================================
    // 2. sort_unstable() — mais rápido, sem garantia de estabilidade
    // =============================================
    let mut valores = vec![5, 2, 8, 1, 9, 3, 7, 4, 6];
    valores.sort_unstable();
    println!("sort_unstable():  {:?}", valores);
    // [1, 2, 3, 4, 5, 6, 7, 8, 9]

    // =============================================
    // 3. reverse() — inverter a ordem
    // =============================================
    valores.reverse();
    println!("reverse():        {:?}", valores);
    // [9, 8, 7, 6, 5, 4, 3, 2, 1]

    // =============================================
    // 4. sort_by() — ordenação com comparador customizado
    // =============================================
    let mut numeros = vec![5, 2, 8, 1, 9, 3];

    // Ordem decrescente
    numeros.sort_by(|a, b| b.cmp(a));
    println!("Decrescente:      {:?}", numeros);
    // [9, 8, 5, 3, 2, 1]

    // Ordenar floats (f64 não implementa Ord, precisa de sort_by)
    let mut decimais = vec![3.14, 1.41, 2.72, 0.58, 1.73];
    decimais.sort_by(|a, b| a.partial_cmp(b).unwrap());
    println!("Floats ordenados: {:?}", decimais);
    // [0.58, 1.41, 1.73, 2.72, 3.14]

    // Floats decrescente
    decimais.sort_by(|a, b| b.partial_cmp(a).unwrap());
    println!("Floats decresc.:  {:?}", decimais);

    // =============================================
    // 5. sort_by_key() — ordenar por uma propriedade
    // =============================================
    let mut palavras = vec!["Rust", "é", "incrível", "e", "rápido"];

    // Ordenar por tamanho da string
    palavras.sort_by_key(|s| s.len());
    println!("Por tamanho:      {:?}", palavras);
    // ["é", "e", "Rust", "rápido", "incrível"]

    // Ordenar por tamanho decrescente
    palavras.sort_by_key(|s| std::cmp::Reverse(s.len()));
    println!("Tamanho decresc.: {:?}", palavras);
    // ["incrível", "rápido", "Rust", "é", "e"]

    // =============================================
    // 6. Ordenar structs customizadas
    // =============================================
    #[derive(Debug, Clone)]
    struct Aluno {
        nome: String,
        nota: f64,
        idade: u32,
    }

    let mut alunos = vec![
        Aluno { nome: "Ana".into(), nota: 9.5, idade: 22 },
        Aluno { nome: "Carlos".into(), nota: 7.0, idade: 25 },
        Aluno { nome: "Bia".into(), nota: 9.5, idade: 20 },
        Aluno { nome: "Daniel".into(), nota: 8.0, idade: 23 },
        Aluno { nome: "Eva".into(), nota: 7.0, idade: 21 },
    ];

    // Ordenar por nota (decrescente)
    alunos.sort_by(|a, b| b.nota.partial_cmp(&a.nota).unwrap());
    println!("\nPor nota (maior primeiro):");
    for a in &alunos {
        println!("  {} — nota: {:.1}, idade: {}", a.nome, a.nota, a.idade);
    }

    // Ordenar por múltiplos critérios: nota (desc), depois nome (asc)
    alunos.sort_by(|a, b| {
        b.nota.partial_cmp(&a.nota)
            .unwrap()
            .then(a.nome.cmp(&b.nome))
    });
    println!("\nPor nota (desc) e nome (asc):");
    for a in &alunos {
        println!("  {} — nota: {:.1}", a.nome, a.nota);
    }

    // =============================================
    // 7. Obter vetor ordenado sem modificar o original
    // =============================================
    let original = vec![3, 1, 4, 1, 5, 9, 2, 6];
    let mut ordenado = original.clone();
    ordenado.sort();
    println!("\nOriginal:  {:?}", original);
    println!("Ordenado:  {:?}", ordenado);

    // =============================================
    // 8. Verificar se já está ordenado
    // =============================================
    let crescente = vec![1, 2, 3, 4, 5];
    let misturado = vec![3, 1, 2];
    println!("\n[1,2,3,4,5] está ordenado? {}", crescente.is_sorted());
    println!("[3,1,2] está ordenado? {}", misturado.is_sorted());

    // =============================================
    // 9. Posição com busca binária (vetor deve estar ordenado)
    // =============================================
    let dados = vec![2, 4, 6, 8, 10, 12, 14];
    match dados.binary_search(&8) {
        Ok(pos) => println!("\n8 encontrado na posição {}", pos),
        Err(pos) => println!("\n8 não encontrado, seria inserido na posição {}", pos),
    }
    match dados.binary_search(&7) {
        Ok(pos) => println!("7 encontrado na posição {}", pos),
        Err(pos) => println!("7 não encontrado, seria inserido na posição {}", pos),
    }
}

Saída do Programa

sort():           [1, 2, 3, 4, 5, 6, 7, 8, 9]
Frutas ordenadas: ["abacaxi", "banana", "cereja", "damasco", "manga"]
sort_unstable():  [1, 2, 3, 4, 5, 6, 7, 8, 9]
reverse():        [9, 8, 7, 6, 5, 4, 3, 2, 1]
Decrescente:      [9, 8, 5, 3, 2, 1]
Floats ordenados: [0.58, 1.41, 1.73, 2.72, 3.14]
Floats decresc.:  [3.14, 2.72, 1.73, 1.41, 0.58]
Por tamanho:      ["é", "e", "Rust", "rápido", "incrível"]
Tamanho decresc.: ["incrível", "rápido", "Rust", "é", "e"]

Por nota (maior primeiro):
  Ana — nota: 9.5, idade: 22
  Bia — nota: 9.5, idade: 20
  Daniel — nota: 8.0, idade: 23
  Carlos — nota: 7.0, idade: 25
  Eva — nota: 7.0, idade: 21

Por nota (desc) e nome (asc):
  Ana — nota: 9.5
  Bia — nota: 9.5
  Daniel — nota: 8.0
  Carlos — nota: 7.0
  Eva — nota: 7.0

Original:  [3, 1, 4, 1, 5, 9, 2, 6]
Ordenado:  [1, 1, 2, 3, 4, 5, 6, 9]

[1,2,3,4,5] está ordenado? true
[3,1,2] está ordenado? false

8 encontrado na posição 3
7 não encontrado, seria inserido na posição 3

Quando Usar Cada Método

MétodoEstávelUso
sort()SimOrdenação padrão (crescente)
sort_unstable()NaoMais rápido; use quando não importa a ordem de iguais
sort_by()SimComparador customizado (decrescente, floats)
sort_by_key()SimOrdenar por uma propriedade extraída
reverse()Inverter a ordem atual

Estável significa que elementos com o mesmo valor mantêm sua ordem relativa original. sort_unstable() é geralmente mais rápido e usa menos memória, sendo a melhor escolha quando a estabilidade não importa.

Veja Também