| Padrão de Controle | Exemplo Típico | Complexidade |
|---|---|---|
| Sem loop | Sequência de instruções primitivas | $O(1)$ |
| 1 loop simples | para i de 0 ate n |
$O(n)$ |
| Loop com divisão | enquanto n > 1: n ← n/2 |
$O(\log n)$ |
| Loop até $\sqrt{n}$ | enquanto i*i ≤ n |
$O(\sqrt{n})$ |
| 2 loops aninhados | para i + para j (dep. de i) |
$O(n^2)$ |
| Série harmônica | $\sum_{i=1}^{n} n/i$ | $O(n \log n)$ |
| Dois ponteiros | Two Sum (ordenado), Palíndromo | $O(n)$ |
V[i] é executado em $O(1)$ sem percorrer o vetor, pois a CPU calcula diretamente o endereço de memória via aritmética de ponteiros:
$$\text{endereço}(V[i]) = \text{endereço\_base} + i \times \text{tamanho\_do\_elemento}$$
| Operação | Complexidade | Razão Teórica |
|---|---|---|
Acesso por índice V[i] |
$O(1)$ | Cálculo direto de endereço (base + $i \times$ size) |
| Busca por valor (linear) | $O(n)$ | Varredura elemento a elemento no pior caso |
| Inserção no fim | $O(1)$ | Atribuição direta se houver espaço pré-alocado |
| Inserção na posição $i$ | $O(n)$ | Deslocamento (shift) de $n - i$ elementos à direita |
| Remoção da posição $i$ | $O(n)$ | Deslocamento (shift) de $n - 1 - i$ elementos à esquerda |
lista[]: O array contíguo que armazena fisicamente os elementos.tamanho: Quantidade lógica atual de elementos inseridos.capacidade: Tamanho físico alocado no vetor interno (ex: capacidade inicial de 4 ou 10).tamanho == capacidade):
index = 0), todos os $n$ elementos atuais precisam ser deslocados uma posição para a direita:
$$\boxed{\text{Pior Caso (index = 0): } O(n)}$$
Inserindo elemento 5 no índice 2:
Antes: [9, 2, 1, 8, 24, _]
↓ Elementos nos índices 2, 3 e 4 movem-se 1 casa à direita
Depois: [9, 2, 5, 1, 8, 24]
tamanho--, sem deslocamentos ⇒ $\boxed{O(1)}$.lista[index]
$$\boxed{O(1)}$$
| Operação | Complexidade | Observação |
|---|---|---|
get(i) |
$O(1)$ | Acesso direto |
add(elem) no fim |
$O(1)$ amort. | Resize eventual $O(n)$ |
add(i, elem) |
$O(n)$ pior caso | Shift à direita |
remove(i) |
$O(n)$ pior caso | Shift à esquerda |
indexOf(elem) |
$O(n)$ | Busca linear |
prev) e outra para o próximo nó (next).
next e referência prev.head) e o fim (tail).novo.next = head, atualiza head.prev = novo e redefine head = novo.tail.next = novo e redefine tail = novo.head: $O(n)$.addFirst) são sempre $O(1)$, sem necessidade de empurrar $n$ elementos nem redimensionar vetores!
head = head.next e limpa a referência anterior. Custo: $O(1)$.tail = tail.prev e limpa a referência seguinte. Custo: $O(1)$.get(index): É necessário caminhar $i$ saltos de ponteiro a partir de head ⇒ $\boxed{O(n)}$.indexOf(elem): Percorre a lista comparando o valor nó a nó até encontrar ou atingir null ⇒ $\boxed{O(n)}$.head.valor ou tail.valor. Custo: $\boxed{O(1)}$.
| Operação | Complexidade | Observação Arquitetural |
|---|---|---|
addFirst / addLast |
$O(1)$ | Manipulação direta de ponteiros em head/tail |
add(i, elem) |
$O(n)$ | Percorrer a cadeia de nós até a posição $i$ |
removeFirst / removeLast |
$O(1)$ | Manipulação direta de ponteiros em head/tail |
remove(i) |
$O(n)$ | Percorrer até a posição do nó desejado |
get(i) |
$O(n)$ | Sem cálculo de endereço direto; travessia sequencial |
getFirst / getLast |
$O(1)$ | Acesso imediato às referências head e tail |
| Operação | ArrayList | LinkedList |
|---|---|---|
Acesso por índice (get(i)) |
$O(1)$ ✓ | $O(n)$ |
Inserção no início (addFirst) |
$O(n)$ (shift obrigatório) | $O(1)$ ✓ |
Inserção no fim (addLast) |
$O(1)$ amort. ✓ | $O(1)$ ✓ |
Remoção do início (removeFirst) |
$O(n)$ (shift obrigatório) | $O(1)$ ✓ |
Remoção do fim (removeLast) |
$O(1)$ ✓ | $O(1)$ ✓ |
| Busca por valor | $O(n)$ | $O(n)$ |
| Uso de memória | Contígua (alta localidade) | Nós + ponteiros (overhead de referências) |
push) e toda remoção (pop) são efetuadas exclusivamente em uma única extremidade denominada topo. O último elemento a entrar é obrigatoriamente o primeiro a sair.
Ctrl+Z / Ctrl+Y).| Operação | Complexidade | Justificativa Algorítmica |
|---|---|---|
push(elem) |
$O(1)$ | Atribuição direta em pilha[topo+1] e incremento |
pop() |
$O(1)$ | Leitura de pilha[topo] e decremento |
peek() |
$O(1)$ | Acesso direto ao elemento pilha[topo] sem remoção |
isEmpty() |
$O(1)$ | Comparação booleana simples: topo == -1 |
addLast / enqueue) é realizada no fim (tail) e toda remoção (removeFirst / dequeue) ocorre na outra ponta, o início (head). O primeiro elemento a entrar é obrigatoriamente o primeiro a sair.
shiftLeft), a remoção custará $O(n)$!
head e tail utilizando aritmética modular com o operador resto de divisão (%):
addLast(a), addLast(b), addLast(c):removeFirst() → a:addLast(d), addLast(e):Total de comparações: 3 (proporcional à altura percorrida $h$).
null) ⇒ insere 45 aqui!| Operação | Melhor Caso (Balanceada, $h = O(\log n)$) | Pior Caso (Degenerada, $h = O(n)$) |
|---|---|---|
| Busca | $O(\log n)$ | $O(n)$ |
| Inserção | $O(\log n)$ | $O(n)$ |
| Remoção | $O(\log n)$ | $O(n)$ |
| Mínimo / Máximo | $O(\log n)$ | $O(n)$ |
| Estratégia | Inserção | Extração do máx. |
|---|---|---|
| Lista ordenada | $O(n)$ | $O(1)$ |
| Lista não ordenada | $O(1)$ | $O(n)$ |
| Heap | $O(\log n)$ | $O(\log n)$ |
| Índice: | [0] | [1] | [2] | [3] | [4] | [5] | [6] |
| Valor: | 88 | 87 | 73 | 47 | 54 | 6 | 0 |
| Operação | Complexidade |
|---|---|
| Inserção (add) | $O(\log n)$ |
| Remoção do máximo (extractMax) | $O(\log n)$ |
| Consulta do máximo (peek) | $O(1)$ |
| Build Heap (a partir de array) | $O(n)$ |
807365841: $807365841 \pmod{10} = \mathbf{1}$ ⇒ Armazena no índice 1 ("Jesse").665422653: $665422653 \pmod{10} = \mathbf{3}$ ⇒ Armazena no índice 3 ("Walter").736217017: $736217017 \pmod{10} = \mathbf{7}$ ⇒ Armazena no índice 7 ("Saul").111382749: $111382749 \pmod{10} = \mathbf{9}$ ⇒ Armazena no índice 9 ("Mike").HashMap) adota $\alpha = 0{,}75$ como limite padrão para disparar o resize.| Operação | Caso Médio (Distribuição Uniforme) | Pior Caso (Todas as chaves colidem) |
|---|---|---|
Inserção (put) |
$O(1)$ | $O(n)$ |
Busca (get) |
$O(1)$ | $O(n)$ |
Remoção (remove) |
$O(1)$ | $O(n)$ |
| Estrutura de Dados | Acesso | Busca | Inserção | Remoção |
|---|---|---|---|---|
| Array / ArrayList | $O(1)$ | $O(n)$ | $O(n)$ ($O(1)$ amort. no fim) | $O(n)$ ($O(1)$ no fim) |
| LinkedList | $O(n)$ | $O(n)$ | $O(1)$ nas pontas / $O(n)$ meio | $O(1)$ nas pontas / $O(n)$ meio |
| Pilha (Stack) | $O(1)$ (topo) | --- | $O(1)$ (push) | $O(1)$ (pop) |
| Fila (Queue) | $O(1)$ (head) | --- | $O(1)$ (enqueue) | $O(1)$ (dequeue) |
| BST (balanceada) | --- | $O(\log n)$ | $O(\log n)$ | $O(\log n)$ |
| BST (degenerada) | --- | $O(n)$ | $O(n)$ | $O(n)$ |
| Heap | $O(1)$ (máximo) | --- | $O(\log n)$ | $O(\log n)$ |
| Tabela Hash | --- | $O(1)$ médio / $O(n)$ pior | $O(1)$ médio / $O(n)$ pior | $O(1)$ médio / $O(n)$ pior |
add(a), add(b), add(c), add(d), add(e).
Quantas operações primitivas (atribuições) são realizadas no total? Qual a complexidade amortizada?
add(a): 1 atribuição direta → Total acumulado: 1add(b): 1 atribuição direta → Total acumulado: 2add(c): 1 atribuição direta → Total acumulado: 3add(d): 1 atribuição direta → Total acumulado: 4 (capacidade 4 esgotada!)add(e): Resize Obrigatório!
Custo Total: $1 + 1 + 1 + 1 + 5 = \mathbf{9\text{ atribuições}}$ para 5 inserções.
Custo Médio Amortizado: $\frac{9}{5} = 1.8\text{ atribuições/inserção} \Longrightarrow \boxed{O(1)\text{ amortizado}}$.
addFirst) manipula exclusivamente as referências do nó e o ponteiro head em tempo constante $O(1)$:
$$\text{Total} = n \times O(1) = \mathbf{O(n)}$$
A árvore é perfeitamente balanceada com altura $h = 2$.
Total: exatamente 3 comparações. Custo $O(h) = O(\log 7) \approx 2.8$ operações!
null).lista seja: (a) uma ArrayList e (b) uma LinkedList.
lista.get(i) é acesso direto em tempo constante $O(1)$:lista.get(i) precisa percorrer $i$ nós desde a cabeça:get(i) dentro de um laço iterando sobre uma LinkedList é um dos antipadrões mais clássicos e destruidores de performance da programação! Para percorrer uma LinkedList em $O(n)$, deve-se obrigatoriamente usar um Iterator / foreach, que avança de nó em nó sem reiniciar da cabeça!
| Estrutura Candidata | Inserção | Busca | Remoção por Valor |
|---|---|---|---|
| ArrayList | $O(1)$ amort. | $O(n)$ | $O(n)$ |
| LinkedList | $O(1)$ | $O(n)$ | $O(n)$ |
| BST Balanceada | $O(\log n)$ | $O(\log n)$ | $O(\log n)$ |
| Tabela Hash | $O(1)$ médio | $O(1)$ médio | $O(1)$ médio |
ArrayList contendo inicialmente $n$ elementos, qual é o custo assintótico total de remover todos os elementos a partir do início (posição de índice 0), um por um, até esvaziar a lista?
Ctrl+Z (desfazer) e Ctrl+Y (refazer).(a) Estrutura da árvore: Como cada valor inserido é estritamente maior que a raiz e que todos os nós anteriores, cada elemento é acoplado como filho direito do elemento anterior: $$1 \longrightarrow 2 \longrightarrow 3 \longrightarrow 4 \longrightarrow 5 \longrightarrow 6 \longrightarrow 7$$ A árvore degenera completamente em uma lista encadeada simples inclinada à direita!
(b) Altura da árvore: $\mathbf{h = 6 = n - 1}$.
(c) Complexidade de buscar o 7: É obrigatório percorrer todos os 7 nós da raiz até a folha 7. Custo de 7 comparações ⇒ $\boxed{O(n)}$.
[10] → 0 trocas.[10, 20] → $20 > \text{pai}(10)$ ⇒ troca ⇒ [20, 10] → 1 troca.[20, 10, 15] → $15 < \text{pai}(20)$ ⇒ 0 trocas.[20, 10, 15, 30] → $30 > \text{pai}(10)$ ⇒ [20, 30, 15, 10] → $30 > \text{pai}(20)$ ⇒ [30, 20, 15, 10] → 2 trocas.[30, 20, 15, 10, 25] → $25 > \text{pai}(20)$ ⇒ [30, 25, 15, 10, 20] → 1 troca.Heap Final: [30, 25, 15, 10, 20] | Total de Trocas: $\boxed{4\text{ trocas}}$.
(a) Posições alocadas:
Todas as 7 chaves são mapeadas para o bucket [0]!
(b) Colisões: Como a primeira chave ocupa o slot e as 6 seguintes colidem no mesmo local, ocorreram exatamente 6 colisões.
(c) Fator de carga: $\alpha = \frac{n}{m} = \frac{7}{11} \approx \mathbf{0.64}$.
| Estrutura | Acesso | Busca | Inserção | Remoção |
|---|---|---|---|---|
| ArrayList | $O(1)$ | $O(n)$ | $O(1)$ amort. fim / $O(n)$ meio | $O(1)$ fim / $O(n)$ meio |
| LinkedList | $O(n)$ | $O(n)$ | $O(1)$ pontas / $O(n)$ meio | $O(1)$ pontas / $O(n)$ meio |
| Pilha (Stack) | $O(1)$ topo | --- | $O(1)$ | $O(1)$ |
| Fila (Queue) | $O(1)$ head | --- | $O(1)$ | $O(1)$ |
| BST (bal.) | --- | $O(\log n)$ | $O(\log n)$ | $O(\log n)$ |
| Heap | $O(1)$ max | --- | $O(\log n)$ | $O(\log n)$ |
| Tabela Hash | --- | $O(1)$ méd. | $O(1)$ méd. | $O(1)$ méd. |
Utilize os controles superiores e simuladores para revisar os conceitos.