---
title: "BTreeSet em Rust: Guia da Stdlib | Rust Brasil"
url: "https://rustlang.com.br/stdlib/btreeset/"
markdown_url: "https://rustlang.com.br/stdlib/btreeset.MD"
description: "Guia completo do BTreeSet em Rust: conjunto ordenado da stdlib com range queries, iteração ordenada e operações de conjunto."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# BTreeSet em Rust: Guia da Stdlib | Rust Brasil

Guia completo do BTreeSet em Rust: conjunto ordenado da stdlib com range queries, iteração ordenada e operações de conjunto.


O `BTreeSet<T>` é a implementação de **conjunto ordenado** da biblioteca padrão do Rust. Ele armazena elementos únicos e os mantém **sempre em ordem crescente**. Internamente, é construído sobre um `BTreeMap<T, ()>`, herdando a eficiência da árvore B com complexidade O(log n) para as operações principais.

## Quando Usar BTreeSet

Use `BTreeSet` quando:

- Precisa de um conjunto de elementos únicos com **iteração em ordem**.
- Deseja realizar **consultas por faixa** (`range`) — por exemplo, "todos os números entre 10 e 50".
- Precisa acessar o **menor** ou **maior** elemento rapidamente.
- O tipo dos elementos implementa `Ord` mas **não** `Hash`.

Se a ordem não importa e você quer busca O(1), use [`HashSet`](/stdlib/hashset/).

## Criando e Inicializando

```rust
use std::collections::BTreeSet;

fn main() {
    // Criar vazio
    let mut numeros: BTreeSet<i32> = BTreeSet::new();

    // Criar a partir de um array
    let vogais = BTreeSet::from(['a', 'e', 'i', 'o', 'u']);

    // Criar a partir de um vetor com collect (remove duplicatas e ordena!)
    let dados = vec![5, 3, 8, 1, 3, 5, 9, 1, 7];
    let ordenados: BTreeSet<i32> = dados.into_iter().collect();
    println!("{:?}", ordenados); // {1, 3, 5, 7, 8, 9}

    // Criar a partir de caracteres de uma string
    let texto = "abracadabra";
    let letras: BTreeSet<char> = texto.chars().collect();
    println!("{:?}", letras); // {'a', 'b', 'c', 'd', 'r'}
}
```

## Tabela de Métodos Comuns

| Método | Descrição | Complexidade |
|---|---|---|
| `insert(value)` | Insere elemento; retorna `true` se era novo | O(log n) |
| `remove(&value)` | Remove elemento; retorna `true` se existia | O(log n) |
| `contains(&value)` | Verifica se o elemento existe | O(log n) |
| `len()` / `is_empty()` | Tamanho e verificação de vazio | O(1) |
| `iter()` | Iterador sobre `&T` em ordem crescente | O(n) |
| `range(range)` | Iterador sobre um intervalo | O(log n + k) |
| `first()` / `last()` | Menor/maior elemento | O(log n) |
| `pop_first()` / `pop_last()` | Remove e retorna menor/maior | O(log n) |
| `union(&other)` | Elementos em `self` OU `other` (em ordem) | O(n + m) |
| `intersection(&other)` | Elementos em `self` E `other` | O(n + m) |
| `difference(&other)` | Elementos em `self` mas NÃO em `other` | O(n + m) |
| `symmetric_difference(&other)` | Em um OU outro, mas não ambos | O(n + m) |
| `is_subset(&other)` | Verifica se `self` ⊆ `other` | O(n + m) |
| `is_superset(&other)` | Verifica se `self` ⊇ `other` | O(n + m) |
| `is_disjoint(&other)` | Verifica se não há elementos em comum | O(n + m) |
| `split_off(&value)` | Divide o conjunto em dois | O(n) |
| `retain(f)` | Mantém elementos onde `f` retorna `true` | O(n) |

## Exemplos Práticos

### 1. Inserção, Busca e Iteração Ordenada

```rust
use std::collections::BTreeSet;

fn main() {
    let mut alunos: BTreeSet<String> = BTreeSet::new();

    alunos.insert("Zara".to_string());
    alunos.insert("Ana".to_string());
    alunos.insert("Miguel".to_string());
    alunos.insert("Bruno".to_string());
    alunos.insert("Ana".to_string()); // duplicata, ignorada

    println!("Total: {} alunos", alunos.len()); // 4

    // Iteração é sempre em ordem alfabética
    println!("Lista de chamada:");
    for (i, aluno) in alunos.iter().enumerate() {
        println!("  {}. {}", i + 1, aluno);
    }
    // 1. Ana
    // 2. Bruno
    // 3. Miguel
    // 4. Zara

    // Verificação de pertinência
    println!("Ana matriculada? {}", alunos.contains("Ana")); // true

    // Primeiro e último
    println!("Primeiro: {:?}", alunos.first()); // Some("Ana")
    println!("Último: {:?}", alunos.last());    // Some("Zara")
}
```

### 2. Range Queries — Consultas por Faixa

```rust
use std::collections::BTreeSet;

fn main() {
    let mut portas: BTreeSet<u16> = BTreeSet::new();

    // Portas de serviços conhecidos
    for porta in [22, 53, 80, 443, 993, 3306, 5432, 6379, 8080, 8443, 27017] {
        portas.insert(porta);
    }

    // Portas "well-known" (0-1023)
    println!("Portas well-known:");
    for porta in portas.range(..1024) {
        println!("  {}", porta);
    }

    // Portas entre 1024 e 9999
    println!("\nPortas registradas:");
    for porta in portas.range(1024..10000) {
        println!("  {}", porta);
    }

    // Portas acima de 5000 (inclusive)
    println!("\nPortas altas (>= 5000):");
    for porta in portas.range(5000..) {
        println!("  {}", porta);
    }

    // Iteração reversa com range
    println!("\nPortas (decrescente):");
    for porta in portas.range(..).rev() {
        print!("{} ", porta);
    }
    println!();
}
```

### 3. Operações de Conjunto

```rust
use std::collections::BTreeSet;

fn main() {
    let primos: BTreeSet<i32> = BTreeSet::from([2, 3, 5, 7, 11, 13, 17, 19]);
    let impares: BTreeSet<i32> = BTreeSet::from([1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);

    // Interseção: primos E ímpares (primos ímpares)
    let primos_impares: BTreeSet<i32> = primos.intersection(&impares).copied().collect();
    println!("Primos ímpares: {:?}", primos_impares);
    // {3, 5, 7, 11, 13, 17, 19}

    // Diferença: primos que NÃO são ímpares (único primo par)
    let primos_pares: BTreeSet<i32> = primos.difference(&impares).copied().collect();
    println!("Primos pares: {:?}", primos_pares); // {2}

    // União: primos OU ímpares
    let todos: BTreeSet<i32> = primos.union(&impares).copied().collect();
    println!("Primos ou ímpares: {:?}", todos);

    // Diferença simétrica: em um OU outro, mas não em ambos
    let exclusivos: BTreeSet<i32> = primos.symmetric_difference(&impares).copied().collect();
    println!("Exclusivos: {:?}", exclusivos); // {1, 2, 9, 15}

    // Os resultados de operações em BTreeSet já vêm em ordem!
    println!("\nSubconjunto? {:?}", primos_pares.is_subset(&primos)); // true
    println!("Disjuntos? {:?}", primos_pares.is_disjoint(&impares)); // true
}
```

### 4. Usando como Fila de Prioridade Simples

```rust
use std::collections::BTreeSet;

fn main() {
    // BTreeSet como agenda de eventos ordenados por timestamp
    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
    struct Evento {
        timestamp: u64,
        descricao: String,
    }

    let mut agenda: BTreeSet<Evento> = BTreeSet::new();

    agenda.insert(Evento {
        timestamp: 1700000000,
        descricao: "Reunião de equipe".to_string(),
    });
    agenda.insert(Evento {
        timestamp: 1699999000,
        descricao: "Café da manhã".to_string(),
    });
    agenda.insert(Evento {
        timestamp: 1700003600,
        descricao: "Almoço".to_string(),
    });

    // Próximo evento (menor timestamp)
    if let Some(proximo) = agenda.first() {
        println!("Próximo evento: {} ({})", proximo.descricao, proximo.timestamp);
    }

    // Processar eventos em ordem
    println!("\nAgenda do dia:");
    for evento in &agenda {
        println!("  [{}] {}", evento.timestamp, evento.descricao);
    }

    // Remover o primeiro evento (já processado)
    if let Some(processado) = agenda.pop_first() {
        println!("\nEvento processado: {}", processado.descricao);
    }
}
```

### 5. Filtrando e Dividindo Conjuntos

```rust
use std::collections::BTreeSet;

fn main() {
    let mut numeros: BTreeSet<i32> = (1..=20).collect();
    println!("Original: {:?}", numeros);

    // retain: manter apenas múltiplos de 3
    let mut multiplos_3 = numeros.clone();
    multiplos_3.retain(|&n| n % 3 == 0);
    println!("Múltiplos de 3: {:?}", multiplos_3); // {3, 6, 9, 12, 15, 18}

    // split_off: dividir em dois conjuntos no valor 11
    let maiores = numeros.split_off(&11);
    println!("Menores que 11: {:?}", numeros);  // {1, 2, ..., 10}
    println!("11 ou mais: {:?}", maiores);       // {11, 12, ..., 20}

    // Combinar dois conjuntos mantendo a ordem
    let pares: BTreeSet<i32> = (0..=10).filter(|n| n % 2 == 0).collect();
    let fibonacci: BTreeSet<i32> = BTreeSet::from([0, 1, 1, 2, 3, 5, 8, 13]);

    let combinados: BTreeSet<i32> = pares.union(&fibonacci).copied().collect();
    println!("Pares ∪ Fibonacci: {:?}", combinados);
}
```

## Características de Desempenho

| Operação | BTreeSet | HashSet |
|---|---|---|
| `insert` | O(log n) | O(1) amortizado |
| `remove` | O(log n) | O(1) amortizado |
| `contains` | O(log n) | O(1) amortizado |
| `first` / `last` | O(log n) | O(n) |
| `range` | O(log n + k) | Indisponível |
| Iteração ordenada | O(n) | O(n log n)* |
| Operações de conjunto | O(n + m) | O(n) ou O(n + m) |

\* `HashSet` requer coletar e ordenar para iteração em ordem.

**Memória:** `BTreeSet` geralmente usa menos memória que `HashSet`, pois a árvore B não precisa de slots vazios na tabela hash. Ambos armazenam os dados no heap.

## BTreeSet vs HashSet

| Critério | BTreeSet | HashSet |
|---|---|---|
| Ordem de iteração | Crescente (garantida) | Não determinística |
| Requisito do tipo | `Ord` | `Eq + Hash` |
| Range queries | Sim (`range()`) | Não |
| Menor/Maior | O(log n) | O(n) |
| Busca individual | O(log n) | O(1) amortizado |
| Uso de memória | Menor | Maior |

**Regra prática:** Use `HashSet` como padrão para conjuntos. Troque para `BTreeSet` quando precisar de ordem, range queries, ou acesso ao menor/maior elemento.

## Veja Também

- [HashSet: Conjunto em Rust](/stdlib/hashset/) --- conjunto não ordenado com busca O(1)
- [BTreeMap: Mapa Ordenado](/stdlib/btreemap/) --- mapa chave-valor baseado na mesma estrutura
- [HashMap em Rust](/stdlib/hashmap/) --- mapa não ordenado
- [BinaryHeap: Fila de Prioridade](/stdlib/binaryheap/) --- quando só precisa do maior/menor elemento
- [Ordenar Vetor em Rust](/receitas/ordenar-vetor/) --- técnicas de ordenação
- [Traits e Generics](/tutoriais/traits-generics/) --- entendendo Ord e PartialOrd
