Ementa — Tipos abstratos de dados
const disciplina = "estruturas"
Estrutura de Dados
3º semestre · segunda-feira · 80 horas-aula
Visão Geral
segunda-feira · 20 aulas no semestre
Visão geral de Estrutura de Dados
Ementa
Estruturas de dados na resolução de problemas computacionais, trabalhando com tipos abstratos de dados, arquivos, alocação de memória, vetores e matrizes dinâmicas. Estruturas de dados lineares e não-lineares: a lista e suas variantes. Métodos de ordenação e de busca.
Objetivo geral
O objetivo geral da disciplina é fazer com que o aluno consiga desenvolver soluções computacionais utilizando recursos avançados de estruturas de dados em seus programas, independente da linguagem de programação que for utilizada.
Metodologia
Aulas teóricas expositivas seguidas de prática de implementação supervisionada. Os códigos são demonstrados ao vivo, e os exercícios são corrigidos antes do avanço para o próximo tópico.
Avaliação
A nota final é NF = (E + 2P1 + 2P2 + T) / 6: exercícios (E), provas práticas P1 em 21/09/2026 e P2 em 30/11/2026 e trabalho apresentado ao final do semestre (T). Há recuperação em 07/12/2026 e exame em 14/12/2026.
Conteúdo programático
- Conceitos básicos sobre estruturas de dados
- Tipos abstratos de dados
- Alocação Dinâmica de Memória
- Manipulação de arquivos
- Estruturas Lineares
- Pilhas: definição, operações e aplicações
- Filas: definição, operações e aplicações
- Listas encadeadas: simplesmente encadeadas, circulares e duplamente encadeadas
- Estruturas não-lineares
- Árvores
- Grafos
- Algoritmos de ordenação
Buscar nesta disciplina
Cronograma
Datas calculadas a partir do dia da semana da disciplina, do início do semestre e dos feriados nacionais.
julho de 2026
agosto de 2026
setembro de 2026
outubro de 2026
novembro de 2026
dezembro de 2026
Ementa — Vetores e matrizes dinâmicas
Manipulação de arquivos
Manipulação de arquivos
Ementa — Complexidade de algoritmos
Ementa — Métodos de busca
Ementa — Vetores e matrizes dinâmicas
Algoritmos de ordenação
Algoritmos de ordenação
Ementa — Complexidade de algoritmos
Estruturas Lineares
Estruturas Lineares
Estruturas Lineares
Estruturas Lineares
Estruturas Lineares
Estruturas não-lineares
Estruturas não-lineares
Ementa — Tipos abstratos de dados
Estruturas não-lineares
Ementa — Tipos abstratos de dados
Apresentação da disciplina e revisão de programação em C
Ementa — Tipos abstratos de dados
Estruturas de dados organizam valores e operações para resolver um problema de forma previsível, eficiente e fácil de manter.
Em palavras simples
Um vetor, uma fila e uma pilha podem guardar números, mas não servem para o mesmo trabalho. A estrutura é a combinação de como os dados ficam organizados e do que se pode fazer com eles. Escolher bem evita código confuso e trabalho desnecessário.
Tecnicamente
Um Tipo Abstrato de Dados (TAD) descreve um conjunto de valores e operações sem obrigar uma implementação. Por exemplo, uma pilha define empilhar, desempilhar e consultar o topo; ela pode ser implementada por vetor ou por nós encadeados. A disciplina compara custos de tempo e memória para escolher a implementação adequada.
Principais conceitos
- Estrutura de dados
- Organização de dados junto às operações que permitem acessá-los e modificá-los.
- TAD
- Contrato de comportamento de uma estrutura, independente de como ela é guardada na memória.
- Implementação
- Representação concreta do TAD, como um vetor, uma lista encadeada ou uma tabela hash.
Exemplos
TAD pilha em operações
Uma pilha segue LIFO: o último item inserido é o primeiro a sair.
empilhar(A)
empilhar(B)
desempilhar() -> B
topo() -> AOnde isso aparece na prática
- Pilhas sustentam desfazer/refazer e a validação de parênteses.
- Filas aparecem no escalonamento de processos, em buffers e em filas de impressão.
- Árvores e grafos modelam índices, sistemas de arquivos, rotas e redes.
Curiosidades
- Lista, fila e pilha são TADs; vetor e lista encadeada são possíveis representações concretas.
- A mesma operação pode ter custo diferente conforme a estrutura escolhida.
Exercícios
Básico
Explique a diferença entre um TAD pilha e uma implementação de pilha com vetor.
Dica
Separe o comportamento que a pilha promete da memória usada para realizá-lo.
Resolução comentada
O TAD define as operações e suas regras: inserir e remover apenas pelo topo, em ordem LIFO. O vetor é apenas uma maneira concreta de reservar posições contíguas para guardar os elementos e controlar o índice do topo.
Resposta
TAD é o contrato de operações; vetor é uma implementação possível desse contrato.
Intermediário
Associe fila ou pilha ao mecanismo de voltar páginas no navegador e justifique a escolha.
Dica
Pergunte qual página deve aparecer primeiro ao voltar.
Resolução comentada
Usa-se uma pilha de histórico: a página visitada por último deve ser a primeira recuperada quando a pessoa usa Voltar. Em geral há uma segunda pilha para permitir Avançar.
Resposta
Pilha, porque a navegação volta na ordem inversa à das visitas.
Resumo
Conceitos importantes
- TAD descreve comportamento; implementação descreve a representação.
- A escolha da estrutura depende das operações mais frequentes.
Checklist
- Sei diferenciar TAD de implementação.
- Sei dar uma aplicação para pilha, fila, árvore e grafo.
Pontos para revisão
- Não confundir a interface de uma estrutura com a forma como ela ocupa memória.
- estrutura de dados
- TAD
- LIFO
- implementação
Prova de diagnóstico e revisão de vetores, matrizes e funções em C
Ementa — Vetores e matrizes dinâmicas
Uma revisão diagnóstica de C identifica se vetores, matrizes, funções, ponteiros e controle de limites estão prontos para os próximos tópicos.
Em palavras simples
Antes de guardar dados em estruturas maiores, é preciso dominar o básico: onde o vetor começa e termina, como percorrer uma matriz e como uma função recebe dados sem copiar tudo desnecessariamente.
Tecnicamente
Vetores em C são blocos contíguos indexados de 0 a n - 1. Matrizes bidimensionais são vetores de vetores em ordem de linhas. Ao passá-los para funções, o tamanho relevante deve acompanhar os dados; nunca se deve acessar índice fora do intervalo válido.
Principais conceitos
- Índice
- Posição de um elemento no vetor; para n elementos válidos, vai de 0 a n - 1.
- Limite
- Tamanho lógico que impede ler ou escrever fora da região reservada.
Onde isso aparece na prática
- Buscar o maior valor de uma coleção.
- Representar tabelas de notas e matrizes numéricas.
- Preparar a passagem de vetores para funções de busca e ordenação.
Curiosidades
- Em C, o nome de um vetor normalmente decai para um ponteiro ao primeiro elemento quando passado a uma função.
Exercícios
Básico
Um vetor possui 12 elementos. Quais são o primeiro e o último índices válidos?
Dica
C começa a contar em zero.
Resolução comentada
O primeiro índice é 0. Como o tamanho é 12, o último é 12 - 1, isto é, 11.
Resposta
0 e 11.
Intermediário
Escreva a quantidade de elementos de uma matriz com 4 linhas e 7 colunas e diga quantas vezes dois laços aninhados a percorrem completamente.
Dica
Cada linha tem todas as colunas.
Resolução comentada
A matriz contém 4 x 7 = 28 elementos. Um laço externo de 4 iterações e outro interno de 7 executa o corpo 28 vezes.
Resposta
28 elementos e 28 execuções do corpo interno.
Resumo
Conceitos importantes
- Vetores usam índices de 0 a n - 1.
- Uma matriz L x C tem L x C elementos.
Checklist
- Sei percorrer vetor sem ultrapassar o limite.
- Sei explicar dois laços para matriz.
Pontos para revisão
- Acesso fora dos limites em C é comportamento indefinido, não um erro automaticamente bloqueado.
- vetor
- matriz
- índice
- limite
Arquivos texto: abertura, leitura, escrita e fechamento
Manipulação de arquivos
Arquivos texto persistem caracteres legíveis e seguem o ciclo abrir, validar, ler ou escrever e fechar.
Em palavras simples
Um arquivo é como um caderno fora da memória do programa. Para usá-lo, o programa abre o caderno, lê ou escreve e o fecha ao terminar. Se não conseguir abrir, não deve fingir que o caderno existe.
Tecnicamente
`fopen` devolve um `FILE *` ou `NULL`. Os modos mais comuns são `r` para leitura, `w` para reescrita e `a` para anexar ao final. `fgets` lê uma linha com limite de tamanho; o seu retorno deve controlar o laço. `fclose` libera o recurso e descarrega buffers pendentes.
Principais conceitos
- FILE *
- Ponteiro que representa o fluxo aberto pelo programa.
- Modo de abertura
- Regra que define se o arquivo será lido, reescrito ou complementado.
- EOF
- Sinal de fim de arquivo; deve ser tratado a partir do resultado de uma leitura.
Exemplos
Leitura linha a linha sem duplicar a última linha
Este padrão corrige o laço `while (!feof(...))`: somente imprime uma linha quando `fgets` realmente a leu.
#include <stdio.h>
int main(void) {
FILE *arquivo = fopen("notas.txt", "r");
char linha[256];
if (arquivo == NULL) {
perror("notas.txt");
return 1;
}
while (fgets(linha, sizeof linha, arquivo) != NULL) {
fputs(linha, stdout);
}
fclose(arquivo);
return 0;
}Linha a linha
fopen("notas.txt", "r")- Abre para leitura; se o caminho não existir ou não houver permissão, retorna NULL.
if (arquivo == NULL)- Interrompe antes de usar um ponteiro inválido.
while (fgets(...) != NULL)- A própria leitura decide se há uma próxima linha.
fclose(arquivo)- Fecha o fluxo em todo caminho de sucesso.
Onde isso aparece na prática
- Importar dados CSV simples.
- Ler configurações e arquivos de log.
- Gerar relatórios que pessoas podem abrir em um editor de texto.
Curiosidades
- O padrão seguro é testar o retorno da operação de leitura, não usar `feof` como condição de laço: o fim só é detectado depois de uma tentativa de leitura.
Exercícios
Básico
Qual modo deve ser usado para acrescentar uma nova linha a um arquivo existente sem apagar as anteriores?
Dica
A palavra inglesa para acrescentar é append.
Resolução comentada
O modo `a` abre para escrita no final. Se o arquivo não existir, ele é criado; se existir, os bytes novos entram depois do conteúdo anterior.
Resposta
`a`.
Intermediário
Por que `while (!feof(arquivo))` pode processar a última linha duas vezes ou usar um valor antigo?
Dica
Quando a função percebe que chegou ao fim?
Resolução comentada
`feof` só se torna verdadeiro depois que uma tentativa de leitura alcança o fim. O corpo entra mais uma vez antes dessa tentativa falhar. O laço deve testar o retorno de `fgets`, `fscanf` ou outra função de leitura.
Resposta
Porque EOF é marcado após uma leitura falhar; teste o retorno da leitura no laço.
Resumo
Conceitos importantes
- Sempre valide o retorno de fopen.
- Controle o laço pelo retorno de fgets, não por feof.
Checklist
- Sei escolher entre r, w e a.
- Sei ler linhas com limite e fechar o arquivo.
Pontos para revisão
- `w` apaga o conteúdo anterior; usar esse modo é uma decisão destrutiva.
- fopen
- fclose
- fgets
- fputs
- EOF
Arquivos binários: registros, fread, fwrite e posicionamento
Manipulação de arquivos
Arquivos binários guardam bytes na representação da memória e permitem ler registros de tamanho conhecido com `fread` e `fwrite`.
Em palavras simples
Texto guarda os símbolos que uma pessoa lê. Binário guarda os bytes que o programa usa. Isso costuma economizar espaço e permite pular diretamente para um registro, mas exige que quem lê conheça o formato.
Tecnicamente
`fwrite(ptr, tamanho, quantidade, arquivo)` grava elementos e devolve quantos foram escritos; `fread` faz o inverso. Um formato simples deve registrar metadados necessários, como a quantidade de elementos. `fseek` desloca em bytes a partir de `SEEK_SET`, `SEEK_CUR` ou `SEEK_END`; se há cabeçalho, ele precisa entrar no deslocamento.
Principais conceitos
- Registro
- Conjunto de bytes que representa uma entidade armazenada no arquivo.
- Cabeçalho
- Dados iniciais que explicam o formato, como quantidade de itens ou versão.
- Acesso direto
- Leitura de uma posição específica sem percorrer todos os registros anteriores.
Exemplos
Gravar um vetor com seu tamanho
O arquivo começa com a quantidade de valores. Assim quem o lê sabe quantos elementos deve esperar.
#include <stdio.h>
int main(void) {
int valores[] = { 8, 13, 21, 34 };
size_t total = sizeof valores / sizeof valores[0];
FILE *arquivo = fopen("valores.bin", "wb");
if (arquivo == NULL) return 1;
if (fwrite(&total, sizeof total, 1, arquivo) != 1 ||
fwrite(valores, sizeof valores[0], total, arquivo) != total) {
fclose(arquivo);
return 1;
}
fclose(arquivo);
return 0;
}Linha a linha
size_t total- Calcula a quantidade sem depender de um número mágico.
fwrite(&total, sizeof total, 1, arquivo)- Grava o cabeçalho antes dos valores.
fwrite(valores, sizeof valores[0], total, arquivo)- Grava todos os inteiros e confirma a quantidade escrita.
Onde isso aparece na prática
- Persistir vetores numéricos compactos.
- Guardar registros de tamanho fixo para acesso direto.
- Ler matrizes e structs quando escritor e leitor controlam o mesmo formato.
Curiosidades
- Um arquivo binário com `int` e `struct` não é automaticamente portátil entre arquiteturas: tamanho, alinhamento e ordem de bytes podem variar.
Exercícios
Básico
Por que um arquivo binário de vetor deve guardar a quantidade de elementos ou outro metadado equivalente?
Dica
Pense em quem abre o arquivo em outra execução.
Resolução comentada
Ao reabrir, o programa não conhece mais o tamanho lógico do vetor que existia na memória. O cabeçalho informa quantos elementos devem ser alocados ou lidos, evitando ler lixo ou parar cedo demais.
Resposta
Porque o tamanho lógico não está na memória após reabrir; o leitor precisa saber quantos elementos há.
Intermediário
Um arquivo começa com um `size_t total` e depois contém inteiros. Escreva o deslocamento para ler o elemento de índice 5 a partir do início.
Dica
Some o cabeçalho aos cinco inteiros que vêm antes do índice 5.
Resolução comentada
O deslocamento é `sizeof(size_t) + 5 * sizeof(int)`. Usar apenas `5 * sizeof(int)` cairia no lugar errado porque ignoraria os bytes do cabeçalho.
Resposta
`sizeof(size_t) + 5 * sizeof(int)`.
Resumo
Conceitos importantes
- fread e fwrite retornam quantos elementos processaram.
- Cabeçalhos tornam o formato interpretável ao reabrir.
Checklist
- Sei diferenciar texto e binário.
- Sei validar fread/fwrite e calcular um deslocamento com cabeçalho.
Pontos para revisão
- Formato binário deve ser documentado; não suponha portabilidade de structs entre plataformas.
- fread
- fwrite
- fseek
- SEEK_SET
- registro
Complexidade de algoritmos: tempo, espaço e escalabilidade
Ementa — Complexidade de algoritmos
Complexidade descreve como o custo de um algoritmo cresce conforme cresce a entrada; Big-O privilegia o termo dominante e ignora constantes.
Em palavras simples
Não basta um programa funcionar para dez valores. É preciso prever o que ocorre com dez mil ou dez milhões. Complexidade é a lente que compara esse crescimento antes de executar o programa em toda escala.
Tecnicamente
A análise assintótica classifica o crescimento do número de operações ou do espaço usado para uma entrada de tamanho n. No pior caso da busca linear, até n elementos são comparados: O(n). Dois laços que percorrem uma matriz n x n executam n² vezes: O(n²). Em Big-O, constantes e termos menores não mudam a classe de crescimento.
Principais conceitos
- Pior caso
- Maior custo possível para uma entrada de tamanho n.
- Caso médio
- Custo esperado sob uma distribuição assumida de entradas.
- Espaço auxiliar
- Memória adicional usada além dos dados de entrada.
- Big-O
- Notação que limita superiormente o crescimento assintótico de um custo.
Exemplos
Zerar uma matriz N x N
Para cada uma das n linhas, o laço interno executa n vezes. O corpo executa n x n vezes, portanto O(n²).
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
matriz[i][j] = 0;Onde isso aparece na prática
- Escolher busca binária para grandes coleções ordenadas.
- Estimar o impacto de laços aninhados antes de processar muitos dados.
- Comparar tempo de execução e espaço auxiliar de duas soluções corretas.
Curiosidades
- Um algoritmo assintoticamente melhor pode perder em entradas pequenas se sua constante oculta for muito alta; isso é a ideia por trás dos chamados algoritmos galáticos.
Exercícios
Básico
Classifique em O(1), O(n) ou O(n²): (a) ler `vetor[7]`; (b) percorrer um vetor; (c) comparar todos os pares de um vetor com dois laços aninhados.
Dica
Conte quantas vezes o corpo mais interno pode executar em função de n.
Resolução comentada
(a) acessa uma posição fixa, O(1). (b) executa uma vez por elemento, O(n). (c) para cada um dos n elementos, percorre até n elementos, O(n²).
Resposta
(a) O(1); (b) O(n); (c) O(n²).
Intermediário
Um algoritmo soma todos os valores de um vetor usando apenas as variáveis `i` e `soma`. Qual é seu espaço auxiliar?
Dica
Não conte o vetor recebido; conte apenas a memória extra.
Resolução comentada
As duas variáveis ocupam quantidade fixa de memória, independente de n. Logo, o espaço auxiliar é O(1), embora o vetor de entrada ocupe O(n).
Resposta
O(1) de espaço auxiliar.
Resumo
Conceitos importantes
- Big-O descreve crescimento, não tempo em segundos.
- Laços aninhados independentes normalmente multiplicam suas iterações.
Checklist
- Sei identificar o termo dominante.
- Sei separar espaço da entrada de espaço auxiliar.
Pontos para revisão
- Constantes importam na prática, mas não alteram a classe assintótica.
- Big-O
- pior caso
- caso médio
- O(n)
- O(n²)
- espaço auxiliar
Busca em vetores: linear, binária e por interpolação
Ementa — Métodos de busca
Busca linear funciona em qualquer vetor; busca binária e interpolação exigem vetor ordenado e trocam esse pré-requisito por menos comparações.
Em palavras simples
Para achar uma palavra numa lista sem ordem, você olha uma por uma. Num dicionário ordenado, abre no meio e escolhe a metade certa. A busca binária faz exatamente essa segunda estratégia.
Tecnicamente
A busca linear tem pior e caso médio O(n), melhor caso O(1). A busca binária reduz o intervalo pela metade a cada passo e tem pior caso O(log n), mas só é correta se os elementos estiverem ordenados. Busca por interpolação estima uma posição proporcional ao valor; pode ter caso médio O(log log n) para distribuição aproximadamente uniforme, mas degrada a O(n) em distribuições desfavoráveis.
Principais conceitos
- Pré-condição
- Condição que deve ser verdadeira antes de executar um algoritmo; na busca binária, o vetor precisa estar ordenado.
- Sentinela
- Valor adicional usado para reduzir uma verificação no laço, sem alterar a ordem de complexidade.
- Intervalo de busca
- Faixa de índices ainda candidata a conter o valor procurado.
Exemplos
Busca binária com intervalo semiaberto
`direita` é exclusivo: o intervalo válido é `[esquerda, direita)`. Isso elimina a necessidade de armazenar `tamanho - 1` em um tipo sem sinal.
int busca_binaria(const int vetor[], size_t tamanho, int valor) {
size_t esquerda = 0;
size_t direita = tamanho;
while (esquerda < direita) {
size_t meio = esquerda + (direita - esquerda) / 2;
if (vetor[meio] == valor) return (int)meio;
if (vetor[meio] < valor) esquerda = meio + 1;
else direita = meio;
}
return -1;
}Linha a linha
direita = tamanho- Define um limite exclusivo, inicialmente logo após o último elemento.
esquerda + (direita - esquerda) / 2- Calcula o meio sem somar dois índices grandes diretamente.
esquerda = meio + 1- Descarta meio e toda a metade esquerda quando o valor do meio é menor.
Onde isso aparece na prática
- Localizar um id em coleção pequena ou não ordenada com busca linear.
- Consultar tabelas ordenadas e índices com busca binária.
- Estimar posições em dados numéricos distribuídos de maneira uniforme.
Curiosidades
- A busca binária é simples em ideia, mas implementações ingênuas podem errar nos limites ou causar overflow ao calcular `(esq + dir) / 2`.
Exercícios
Básico
Por que não é correto aplicar busca binária ao vetor `[8, 3, 12, 5]`?
Dica
Depois de comparar com o meio, qual metade poderia ser descartada com segurança?
Resolução comentada
A busca binária decide qual metade descartar supondo que valores menores ficam de um lado e maiores do outro. No vetor desordenado essa inferência é falsa; o valor procurado pode estar justamente na metade descartada.
Resposta
Porque o vetor não está ordenado, então descartar uma metade pode eliminar o valor procurado.
Intermediário
Em um vetor ordenado de 1 024 elementos, aproximadamente quantas divisões pela metade são necessárias no pior caso de busca binária?
Dica
1024 é uma potência de 2.
Resolução comentada
Como 2¹⁰ = 1024, cada divisão remove metade do intervalo até restar uma posição. A ordem é de 10 comparações, isto é, O(log n).
Resposta
Cerca de 10 divisões/comparações de nível.
Resumo
Conceitos importantes
- Busca linear não exige ordem; busca binária exige.
- Busca binária reduz o intervalo pela metade e escala em O(log n).
Checklist
- Sei escolher busca linear ou binária conforme a entrada.
- Sei justificar a pré-condição de ordenação.
Pontos para revisão
- Otimizar comparações com sentinela não muda a complexidade assintótica.
- busca linear
- busca binária
- interpolação
- vetor ordenado
- O(log n)
Atividade extra: implementação de multiplicação de matrizes
Ementa — Vetores e matrizes dinâmicas
A multiplicação de matrizes exercita leitura estruturada, validação de dimensões, laços aninhados e análise de complexidade cúbica.
Em palavras simples
Para multiplicar A por B, cada linha de A conversa com cada coluna de B. O resultado só existe quando o número de colunas de A é igual ao número de linhas de B.
Tecnicamente
Se A tem L1 x C1 e B tem L2 x C2, A x B existe somente se C1 = L2 e produz matriz L1 x C2. Cada resultado `[i][j]` é a soma de `A[i][k] * B[k][j]` para k de 0 a C1 - 1. Para matrizes quadradas n x n, os três laços executam O(n³) operações.
Principais conceitos
- Compatibilidade
- Condição C1 = L2 que permite multiplicar A(L1 x C1) por B(L2 x C2).
- Produto escalar
- Soma dos produtos entre uma linha de A e uma coluna de B.
Exemplos
Multiplicação com validação de dimensões
Versão didática com limites fixos para acompanhar a atividade. Em produção, as dimensões lidas devem ser validadas antes de acessar as matrizes.
#include <stdio.h>
int main(void) {
int linhasA, colunasA, linhasB, colunasB;
float a[50][50], b[50][50], resultado[50][50] = {0};
scanf("%d %d", &linhasA, &colunasA);
for (int i = 0; i < linhasA; i++)
for (int j = 0; j < colunasA; j++) scanf("%f", &a[i][j]);
scanf("%d %d", &linhasB, &colunasB);
for (int i = 0; i < linhasB; i++)
for (int j = 0; j < colunasB; j++) scanf("%f", &b[i][j]);
if (colunasA != linhasB) {
puts("ERRO");
return 0;
}
for (int i = 0; i < linhasA; i++)
for (int j = 0; j < colunasB; j++)
for (int k = 0; k < colunasA; k++)
resultado[i][j] += a[i][k] * b[k][j];
for (int i = 0; i < linhasA; i++) {
for (int j = 0; j < colunasB; j++) printf("%.0f ", resultado[i][j]);
puts("");
}
}Linha a linha
colunasA != linhasB- Garante que cada linha de A tenha o mesmo tamanho de cada coluna de B.
resultado[i][j] +=- Acumula o produto escalar; por isso a matriz começa zerada.
for (int k = 0; k < colunasA; k++)- Percorre os pares correspondentes da linha e da coluna.
Onde isso aparece na prática
- Transformações gráficas e computação científica.
- Composição de relações e caminhos em grafos por matriz de adjacência.
- Exercício de leitura de entrada e validação antes do processamento.
Curiosidades
- O enunciado do VPL pede encerrar com `ERRO` quando C1 for diferente de L2; essa validação deve acontecer antes dos três laços.
Exercícios
Básico
Qual é a dimensão do resultado de uma matriz 2 x 3 multiplicada por uma matriz 3 x 5?
Dica
As dimensões internas precisam coincidir; ficam as externas.
Resolução comentada
As dimensões internas são 3 e 3, então o produto é válido. A matriz resultante mantém as dimensões externas: 2 linhas de A e 5 colunas de B.
Resposta
2 x 5.
Intermediário
Explique por que uma matriz 4 x 2 não pode ser multiplicada por uma matriz 3 x 4 nessa ordem.
Dica
Compare colunas da primeira com linhas da segunda.
Resolução comentada
A primeira tem 2 colunas, mas a segunda tem 3 linhas. Não é possível formar pares completos entre uma linha de A e uma coluna de B, portanto a regra C1 = L2 falha.
Resposta
Porque 2 != 3; as dimensões internas não são compatíveis.
Resumo
Conceitos importantes
- A(L1 x C1) x B(L2 x C2) exige C1 = L2 e resulta em L1 x C2.
- O algoritmo clássico usa três laços e é O(n³) para matrizes quadradas.
Checklist
- Sei validar dimensões antes do cálculo.
- Sei explicar o papel de i, j e k nos três laços.
Pontos para revisão
- Inicializar o resultado com zero é necessário porque cada célula acumula vários produtos.
- matriz
- produto escalar
- dimensões
- O(n³)
Ordenação de vetores
Algoritmos de ordenação
Ordenar reorganiza os elementos por uma chave para facilitar busca, leitura e processamento posterior.
Em palavras simples
Ordenar uma lista é colocar os itens numa ordem combinada, como notas da menor para a maior.
Tecnicamente
Algoritmos de ordenação podem comparar e trocar elementos, como bubble sort e selection sort. A análise deve considerar custo temporal, uso de memória, estabilidade e se o algoritmo altera o vetor original.
Principais conceitos
- Estabilidade
- Propriedade de preservar a ordem relativa de elementos com a mesma chave.
- In-place
- Algoritmo que usa pouca memória adicional e altera a própria coleção.
Onde isso aparece na prática
- Preparar dados para busca binária e relatórios ordenados.
Exercícios
Intermediário
Por que ordenar um vetor pode ser útil antes de realizar várias buscas nele?
Dica
Compare o custo de organizar uma vez com o de procurar muitas vezes.
Resolução comentada
Depois de ordenado, o vetor pode usar busca binária em O(log n). Quando haverá muitas consultas, o custo inicial de ordenar pode compensar a redução em cada busca.
Resposta
Porque habilita busca binária e reduz o custo de muitas consultas.
Resumo
Conceitos importantes
- Ordenar reorganiza os elementos por uma chave para facilitar busca, leitura e processamento posterior.
- Estabilidade: Propriedade de preservar a ordem relativa de elementos com a mesma chave.
- In-place: Algoritmo que usa pouca memória adicional e altera a própria coleção.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- Algoritmos de ordenação podem comparar e trocar elementos, como bubble sort e selection sort. A análise deve considerar custo temporal, uso de memória, estabilidade e se o algoritmo altera o vetor original.
- Estabilidade
- In-place
Atividade extra: prática de ordenação e busca
Algoritmos de ordenação
A atividade extra consolida a relação entre dados ordenados, algoritmo de ordenação e busca eficiente.
Em palavras simples
Primeiro coloque em ordem; depois use a ordem para encontrar mais rápido.
Tecnicamente
A escolha entre ordenar e buscar linearmente depende da quantidade de buscas esperada, do custo de atualização e da necessidade de preservar a ordem de entrada.
Principais conceitos
- Custo amortizado
- Custo médio de uma sequência de operações, incluindo um preparo inicial como a ordenação.
Onde isso aparece na prática
- Catálogos que recebem dados em lote e são consultados muitas vezes.
Exercícios
Básico
Uma lista será consultada apenas uma vez. Em que situação a busca linear pode ser preferível a ordenar e usar busca binária?
Dica
Leve em conta o trabalho extra de ordenar.
Resolução comentada
Para uma única busca, especialmente em lista pequena ou sem ordem prévia, ordenar pode custar mais do que percorrer uma vez. Busca linear evita o preparo quando ele não será reaproveitado.
Resposta
Quando haverá só uma consulta e o custo de ordenar não será reaproveitado.
Resumo
Conceitos importantes
- A atividade extra consolida a relação entre dados ordenados, algoritmo de ordenação e busca eficiente.
- Custo amortizado: Custo médio de uma sequência de operações, incluindo um preparo inicial como a ordenação.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- A escolha entre ordenar e buscar linearmente depende da quantidade de buscas esperada, do custo de atualização e da necessidade de preservar a ordem de entrada.
- Custo amortizado
Prova 1: arquivos, complexidade, busca e ordenação
Ementa — Complexidade de algoritmos
Momento de integrar persistência em arquivos, análise de custo, busca em vetores e ordenação.
Em palavras simples
A prova cobra escolher a ferramenta certa e explicar por quê, não só decorar nomes.
Tecnicamente
Revise pré-condições de algoritmos, validação de retornos de funções de arquivo, limites de vetores e classes O(1), O(log n), O(n), O(n²) e O(n³).
Principais conceitos
- Pré-condição
- Condição necessária antes de executar um algoritmo.
Onde isso aparece na prática
- Elaborar um roteiro de revisão com exemplos pequenos executados à mão.
Exercícios
Básico
Monte uma tabela comparando busca linear e binária: requisito, pior caso e melhor caso.
Dica
A diferença central é a ordem do vetor.
Resolução comentada
Linear: funciona sem ordenação, pior O(n), melhor O(1). Binária: exige vetor ordenado, pior O(log n), melhor O(1).
Resposta
Linear: sem ordem/O(n)/O(1); binária: ordenado/O(log n)/O(1).
Resumo
Conceitos importantes
- Momento de integrar persistência em arquivos, análise de custo, busca em vetores e ordenação.
- Pré-condição: Condição necessária antes de executar um algoritmo.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- Revise pré-condições de algoritmos, validação de retornos de funções de arquivo, limites de vetores e classes O(1), O(log n), O(n), O(n²) e O(n³).
- Pré-condição
Listas e Array Lists
Estruturas Lineares
Listas representam sequências; uma array list usa vetor redimensionável para equilibrar acesso por índice e crescimento.
Em palavras simples
Uma lista guarda itens em sequência. Quando ela usa vetor por baixo, achar uma posição é rápido, mas abrir espaço no meio exige deslocar itens.
Tecnicamente
Em vetor dinâmico, acesso por índice é O(1). Inserção ou remoção no meio pode exigir deslocar O(n) elementos. Redimensionar costuma copiar o bloco, mas pode ter custo amortizado constante em inserções no final.
Principais conceitos
- Array list
- Lista baseada em vetor redimensionável.
- Capacidade
- Quantidade de posições alocadas, que pode ser maior que o tamanho lógico.
Onde isso aparece na prática
- Coleções com muitas leituras por posição e inserções principalmente no final.
Exercícios
Básico
Qual operação tende a ser mais cara numa array list: ler o índice 20 ou inserir na posição 0? Justifique.
Dica
Uma das operações desloca elementos.
Resolução comentada
Ler índice 20 é acesso direto, O(1). Inserir no início desloca os elementos existentes uma posição, portanto pode ser O(n).
Resposta
Inserir na posição 0, pois pode deslocar todos os elementos.
Resumo
Conceitos importantes
- Listas representam sequências; uma array list usa vetor redimensionável para equilibrar acesso por índice e crescimento.
- Array list: Lista baseada em vetor redimensionável.
- Capacidade: Quantidade de posições alocadas, que pode ser maior que o tamanho lógico.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- Em vetor dinâmico, acesso por índice é O(1). Inserção ou remoção no meio pode exigir deslocar O(n) elementos. Redimensionar costuma copiar o bloco, mas pode ter custo amortizado constante em inserções no final.
- Array list
- Capacidade
Listas encadeadas
Estruturas Lineares
Listas encadeadas guardam cada elemento em um nó ligado ao próximo, favorecendo inserções e remoções quando a posição já é conhecida.
Em palavras simples
Em vez de uma fila de caixas lado a lado, cada caixa aponta para a próxima. Para chegar à caixa 20 é preciso seguir as anteriores; para encaixar uma caixa depois da atual basta trocar ligações.
Tecnicamente
Um nó normalmente contém dado e ponteiro `proximo`. Acesso por índice exige percorrer nós, O(n). Inserção após um nó conhecido e remoção do próximo podem ser O(1), desde que os ponteiros sejam atualizados sem perder referências.
Principais conceitos
- Nó
- Unidade que contém um valor e referências para outros nós.
- Cabeça
- Referência ao primeiro nó da lista.
Onde isso aparece na prática
- Filas, pilhas e coleções com inserções frequentes em posições já localizadas.
Exercícios
Básico
Por que acessar o elemento de índice 500 em lista encadeada não é O(1)?
Dica
Há endereço calculável para cada nó?
Resolução comentada
Os nós não ocupam posições contíguas conhecidas pelo índice. É preciso seguir o ponteiro do primeiro nó ao próximo repetidamente até chegar ao índice pedido.
Resposta
Porque é preciso percorrer os nós desde a cabeça até alcançar o índice.
Resumo
Conceitos importantes
- Listas encadeadas guardam cada elemento em um nó ligado ao próximo, favorecendo inserções e remoções quando a posição já é conhecida.
- Nó: Unidade que contém um valor e referências para outros nós.
- Cabeça: Referência ao primeiro nó da lista.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- Um nó normalmente contém dado e ponteiro `proximo`. Acesso por índice exige percorrer nós, O(n). Inserção após um nó conhecido e remoção do próximo podem ser O(1), desde que os ponteiros sejam atualizados sem perder referências.
- Nó
- Cabeça
Pilhas
Estruturas Lineares
Pilha implementa LIFO: o último elemento inserido é o primeiro removido.
Em palavras simples
Pense numa pilha de pratos: só é possível colocar ou retirar o prato do topo.
Tecnicamente
As operações principais são `push`, `pop` e `peek`. Em implementação por vetor com topo controlado ou por lista encadeada na cabeça, essas operações podem ser O(1).
Principais conceitos
- LIFO
- Last In, First Out: último a entrar, primeiro a sair.
- Topo
- Única extremidade acessível para inserção e remoção.
Onde isso aparece na prática
- Desfazer/refazer, chamada de funções e validação de delimitadores.
Exercícios
Básico
Após `push(4)`, `push(9)`, `pop()`, qual valor resta no topo?
Dica
Pop remove o último inserido.
Resolução comentada
O `pop` remove 9; 4 continua sendo o elemento no topo.
Resposta
4.
Resumo
Conceitos importantes
- Pilha implementa LIFO: o último elemento inserido é o primeiro removido.
- LIFO: Last In, First Out: último a entrar, primeiro a sair.
- Topo: Única extremidade acessível para inserção e remoção.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- As operações principais são `push`, `pop` e `peek`. Em implementação por vetor com topo controlado ou por lista encadeada na cabeça, essas operações podem ser O(1).
- LIFO
- Topo
Atividade extra: aplicações de pilhas
Estruturas Lineares
A prática com pilhas explora a invariável de que somente o topo pode mudar a cada operação.
Em palavras simples
A pilha ajuda quando a ordem de volta é o contrário da ordem de chegada.
Tecnicamente
Na verificação de parênteses, abre-se um delimitador com push e fecha-se com pop compatível. A pilha vazia antes do fim ou não vazia ao final indica expressão inválida.
Principais conceitos
- Invariável
- Propriedade que deve permanecer verdadeira durante a execução do algoritmo.
Onde isso aparece na prática
- Analisadores de expressões e editores com desfazer/refazer.
Exercícios
Básico
A expressão `(a + [b])` é balanceada? E `(a + [b)`?
Dica
Fechamentos devem corresponder ao último delimitador aberto.
Resolução comentada
A primeira é balanceada: fecha `]` antes de `)`. A segunda deixa `[` aberto e tenta fechar `)` antes dele, portanto é inválida.
Resposta
A primeira é válida; a segunda é inválida.
Resumo
Conceitos importantes
- A prática com pilhas explora a invariável de que somente o topo pode mudar a cada operação.
- Invariável: Propriedade que deve permanecer verdadeira durante a execução do algoritmo.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- Na verificação de parênteses, abre-se um delimitador com push e fecha-se com pop compatível. A pilha vazia antes do fim ou não vazia ao final indica expressão inválida.
- Invariável
Filas e deques
Estruturas Lineares
Fila usa FIFO; deque permite inserir e remover nas duas extremidades.
Em palavras simples
Numa fila normal, quem chega primeiro é atendido primeiro. No deque, as duas pontas ficam disponíveis.
Tecnicamente
Fila opera com inserção no fim e remoção no início. Deque generaliza a estrutura com operações em ambas as extremidades. Uma implementação circular em vetor reaproveita posições liberadas sem deslocar elementos.
Principais conceitos
- FIFO
- First In, First Out: primeiro a entrar, primeiro a sair.
- Deque
- Double-ended queue, fila com operações nas duas pontas.
Onde isso aparece na prática
- Fila de impressão, escalonamento e janelas deslizantes.
Exercícios
Básico
Após enfileirar A, B e C, qual elemento sai no próximo desenfileiramento?
Dica
A fila preserva a ordem de chegada.
Resolução comentada
A entrou antes de B e C, por isso está na frente e é removida primeiro.
Resposta
A.
Resumo
Conceitos importantes
- Fila usa FIFO; deque permite inserir e remover nas duas extremidades.
- FIFO: First In, First Out: primeiro a entrar, primeiro a sair.
- Deque: Double-ended queue, fila com operações nas duas pontas.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- Fila opera com inserção no fim e remoção no início. Deque generaliza a estrutura com operações em ambas as extremidades. Uma implementação circular em vetor reaproveita posições liberadas sem deslocar elementos.
- FIFO
- Deque
Árvores
Estruturas não-lineares
Árvores modelam relações hierárquicas com raiz, nós, arestas e subárvores.
Em palavras simples
Uma árvore parece a estrutura de pastas: há uma origem e cada pasta pode levar a outras.
Tecnicamente
Em árvore enraizada, cada nó, exceto a raiz, tem um pai. Árvores binárias limitam cada nó a até dois filhos. Percursos pré-ordem, em ordem e pós-ordem visitam nós com regras diferentes.
Principais conceitos
- Raiz
- Nó sem pai, ponto inicial da árvore.
- Folha
- Nó sem filhos.
Onde isso aparece na prática
- Sistemas de arquivos, árvores de expressão e índices de banco de dados.
Exercícios
Básico
Um nó sem filhos recebe qual nome?
Dica
Pense na ponta de um galho.
Resolução comentada
Nó sem filhos é uma folha, pois encerra um caminho da árvore.
Resposta
Folha.
Resumo
Conceitos importantes
- Árvores modelam relações hierárquicas com raiz, nós, arestas e subárvores.
- Raiz: Nó sem pai, ponto inicial da árvore.
- Folha: Nó sem filhos.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- Em árvore enraizada, cada nó, exceto a raiz, tem um pai. Árvores binárias limitam cada nó a até dois filhos. Percursos pré-ordem, em ordem e pós-ordem visitam nós com regras diferentes.
- Raiz
- Folha
Grafos
Estruturas não-lineares
Grafos representam entidades ligadas por relações, sem exigir uma hierarquia única como árvores.
Em palavras simples
Um grafo é um mapa de pontos e conexões: cidades e estradas, pessoas e amizades, páginas e links.
Tecnicamente
Um grafo G = (V, E) possui conjunto de vértices V e arestas E. Pode ser direcionado ou não direcionado, ponderado ou não. Lista de adjacência economiza espaço em grafos esparsos; matriz de adjacência favorece consulta direta de ligação.
Principais conceitos
- Vértice
- Entidade ou ponto do grafo.
- Aresta
- Ligação entre dois vértices.
Onde isso aparece na prática
- Rotas, redes sociais, dependências de tarefas e redes de computadores.
Exercícios
Básico
Qual representação tende a economizar memória quando cada vértice se liga a poucos outros: matriz ou lista de adjacência?
Dica
Compare guardar todas as combinações possíveis com guardar apenas as conexões existentes.
Resolução comentada
Lista de adjacência guarda apenas arestas existentes e tende a usar O(V + E). Matriz reserva O(V²) posições mesmo quando quase não há ligações.
Resposta
Lista de adjacência.
Resumo
Conceitos importantes
- Grafos representam entidades ligadas por relações, sem exigir uma hierarquia única como árvores.
- Vértice: Entidade ou ponto do grafo.
- Aresta: Ligação entre dois vértices.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- Um grafo G = (V, E) possui conjunto de vértices V e arestas E. Pode ser direcionado ou não direcionado, ponderado ou não. Lista de adjacência economiza espaço em grafos esparsos; matriz de adjacência favorece consulta direta de ligação.
- Vértice
- Aresta
Apresentação dos trabalhos
Ementa — Tipos abstratos de dados
A apresentação deve tornar explícitas a estrutura escolhida, as operações implementadas, os custos e os testes realizados.
Em palavras simples
Não basta mostrar que funcionou: explique qual problema o programa resolve e por que a estrutura escolhida combina com ele.
Tecnicamente
Uma apresentação técnica deve declarar requisitos, representação de dados, invariantes, casos de borda, complexidades principais e evidências de teste. Isso conecta implementação a decisão de projeto.
Principais conceitos
- Caso de borda
- Entrada válida extrema ou especial que frequentemente revela falhas de implementação.
Onde isso aparece na prática
- Documentar e defender escolhas técnicas em equipe.
Exercícios
Básico
Liste dois casos de borda para uma fila vazia.
Dica
Pense em remover e consultar sem elementos.
Resolução comentada
Desenfileirar fila vazia e consultar frente de fila vazia devem ser definidos e testados; a implementação não pode acessar memória inexistente.
Resposta
Remover de fila vazia e consultar sua frente são dois casos de borda.
Resumo
Conceitos importantes
- A apresentação deve tornar explícitas a estrutura escolhida, as operações implementadas, os custos e os testes realizados.
- Caso de borda: Entrada válida extrema ou especial que frequentemente revela falhas de implementação.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- Uma apresentação técnica deve declarar requisitos, representação de dados, invariantes, casos de borda, complexidades principais e evidências de teste. Isso conecta implementação a decisão de projeto.
- Caso de borda
Prova 2: listas, pilhas, filas, árvores e grafos
Estruturas não-lineares
A segunda prova integra estruturas lineares e não lineares, suas operações e seus custos.
Em palavras simples
Revise qual estrutura atende cada regra de acesso: topo, frente, índice, hierarquia ou conexão.
Tecnicamente
Compare contratos e complexidades: acesso em vetor, percurso em lista encadeada, push/pop, enqueue/dequeue, percursos de árvore e representações de grafo.
Principais conceitos
- Contrato de acesso
- Regra que limita quais elementos podem ser lidos ou removidos em uma estrutura.
Onde isso aparece na prática
- Selecionar estrutura a partir das operações requeridas pelo problema.
Exercícios
Básico
Qual estrutura escolher para processar tarefas na ordem de chegada: pilha ou fila?
Dica
A primeira tarefa deve sair primeiro.
Resolução comentada
Fila segue FIFO e preserva a ordem de chegada. Pilha inverteria a ordem ao remover a tarefa mais recente primeiro.
Resposta
Fila.
Resumo
Conceitos importantes
- A segunda prova integra estruturas lineares e não lineares, suas operações e seus custos.
- Contrato de acesso: Regra que limita quais elementos podem ser lidos ou removidos em uma estrutura.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- Compare contratos e complexidades: acesso em vetor, percurso em lista encadeada, push/pop, enqueue/dequeue, percursos de árvore e representações de grafo.
- Contrato de acesso
Recuperação e revisão integradora
Ementa — Tipos abstratos de dados
A recuperação revisa decisões de estrutura, implementação em C, análise de complexidade e tratamento de casos de borda.
Em palavras simples
Use os erros anteriores como roteiro: descubra onde a regra foi confundida e pratique um exemplo pequeno até conseguir explicá-lo.
Tecnicamente
Uma revisão eficaz alterna recuperação ativa, execução manual de algoritmos, comparação de complexidades e leitura crítica de código, especialmente validações, limites e retornos de funções.
Principais conceitos
- Recuperação ativa
- Técnica de tentar lembrar e resolver antes de consultar a resposta.
Onde isso aparece na prática
- Planejar estudo final por lacunas reais em vez de apenas reler resumos.
Exercícios
Desafio
Escolha um algoritmo da disciplina e explique sua pré-condição e seu pior caso em duas frases.
Dica
Busca binária é um bom ponto de partida.
Resolução comentada
Exemplo: busca binária exige vetor ordenado; no pior caso reduz o intervalo até esvaziá-lo, realizando O(log n) comparações. A resposta pode usar outro algoritmo, desde que condição e custo sejam coerentes.
Resposta
Resposta varia; deve relacionar corretamente a pré-condição ao pior caso do algoritmo escolhido.
Resumo
Conceitos importantes
- A recuperação revisa decisões de estrutura, implementação em C, análise de complexidade e tratamento de casos de borda.
- Recuperação ativa: Técnica de tentar lembrar e resolver antes de consultar a resposta.
Checklist
- Consigo explicar o conceito sem consultar o material.
- Resolvi o exercício e conferi a justificativa.
Pontos para revisão
- Uma revisão eficaz alterna recuperação ativa, execução manual de algoritmos, comparação de complexidades e leitura crítica de código, especialmente validações, limites e retornos de funções.
- Recuperação ativa
Exercícios
Todos os exercícios da disciplina reunidos, na ordem das aulas.
Básico (18)
Explique a diferença entre um TAD pilha e uma implementação de pilha com vetor.
Dica
Separe o comportamento que a pilha promete da memória usada para realizá-lo.
Resolução comentada
O TAD define as operações e suas regras: inserir e remover apenas pelo topo, em ordem LIFO. O vetor é apenas uma maneira concreta de reservar posições contíguas para guardar os elementos e controlar o índice do topo.
Resposta
TAD é o contrato de operações; vetor é uma implementação possível desse contrato.
Um vetor possui 12 elementos. Quais são o primeiro e o último índices válidos?
Dica
C começa a contar em zero.
Resolução comentada
O primeiro índice é 0. Como o tamanho é 12, o último é 12 - 1, isto é, 11.
Resposta
0 e 11.
Qual modo deve ser usado para acrescentar uma nova linha a um arquivo existente sem apagar as anteriores?
Dica
A palavra inglesa para acrescentar é append.
Resolução comentada
O modo `a` abre para escrita no final. Se o arquivo não existir, ele é criado; se existir, os bytes novos entram depois do conteúdo anterior.
Resposta
`a`.
Por que um arquivo binário de vetor deve guardar a quantidade de elementos ou outro metadado equivalente?
Dica
Pense em quem abre o arquivo em outra execução.
Resolução comentada
Ao reabrir, o programa não conhece mais o tamanho lógico do vetor que existia na memória. O cabeçalho informa quantos elementos devem ser alocados ou lidos, evitando ler lixo ou parar cedo demais.
Resposta
Porque o tamanho lógico não está na memória após reabrir; o leitor precisa saber quantos elementos há.
Classifique em O(1), O(n) ou O(n²): (a) ler `vetor[7]`; (b) percorrer um vetor; (c) comparar todos os pares de um vetor com dois laços aninhados.
Dica
Conte quantas vezes o corpo mais interno pode executar em função de n.
Resolução comentada
(a) acessa uma posição fixa, O(1). (b) executa uma vez por elemento, O(n). (c) para cada um dos n elementos, percorre até n elementos, O(n²).
Resposta
(a) O(1); (b) O(n); (c) O(n²).
Por que não é correto aplicar busca binária ao vetor `[8, 3, 12, 5]`?
Dica
Depois de comparar com o meio, qual metade poderia ser descartada com segurança?
Resolução comentada
A busca binária decide qual metade descartar supondo que valores menores ficam de um lado e maiores do outro. No vetor desordenado essa inferência é falsa; o valor procurado pode estar justamente na metade descartada.
Resposta
Porque o vetor não está ordenado, então descartar uma metade pode eliminar o valor procurado.
Qual é a dimensão do resultado de uma matriz 2 x 3 multiplicada por uma matriz 3 x 5?
Dica
As dimensões internas precisam coincidir; ficam as externas.
Resolução comentada
As dimensões internas são 3 e 3, então o produto é válido. A matriz resultante mantém as dimensões externas: 2 linhas de A e 5 colunas de B.
Resposta
2 x 5.
Uma lista será consultada apenas uma vez. Em que situação a busca linear pode ser preferível a ordenar e usar busca binária?
Dica
Leve em conta o trabalho extra de ordenar.
Resolução comentada
Para uma única busca, especialmente em lista pequena ou sem ordem prévia, ordenar pode custar mais do que percorrer uma vez. Busca linear evita o preparo quando ele não será reaproveitado.
Resposta
Quando haverá só uma consulta e o custo de ordenar não será reaproveitado.
Monte uma tabela comparando busca linear e binária: requisito, pior caso e melhor caso.
Dica
A diferença central é a ordem do vetor.
Resolução comentada
Linear: funciona sem ordenação, pior O(n), melhor O(1). Binária: exige vetor ordenado, pior O(log n), melhor O(1).
Resposta
Linear: sem ordem/O(n)/O(1); binária: ordenado/O(log n)/O(1).
Qual operação tende a ser mais cara numa array list: ler o índice 20 ou inserir na posição 0? Justifique.
Dica
Uma das operações desloca elementos.
Resolução comentada
Ler índice 20 é acesso direto, O(1). Inserir no início desloca os elementos existentes uma posição, portanto pode ser O(n).
Resposta
Inserir na posição 0, pois pode deslocar todos os elementos.
Por que acessar o elemento de índice 500 em lista encadeada não é O(1)?
Dica
Há endereço calculável para cada nó?
Resolução comentada
Os nós não ocupam posições contíguas conhecidas pelo índice. É preciso seguir o ponteiro do primeiro nó ao próximo repetidamente até chegar ao índice pedido.
Resposta
Porque é preciso percorrer os nós desde a cabeça até alcançar o índice.
Após `push(4)`, `push(9)`, `pop()`, qual valor resta no topo?
Dica
Pop remove o último inserido.
Resolução comentada
O `pop` remove 9; 4 continua sendo o elemento no topo.
Resposta
4.
A expressão `(a + [b])` é balanceada? E `(a + [b)`?
Dica
Fechamentos devem corresponder ao último delimitador aberto.
Resolução comentada
A primeira é balanceada: fecha `]` antes de `)`. A segunda deixa `[` aberto e tenta fechar `)` antes dele, portanto é inválida.
Resposta
A primeira é válida; a segunda é inválida.
Após enfileirar A, B e C, qual elemento sai no próximo desenfileiramento?
Dica
A fila preserva a ordem de chegada.
Resolução comentada
A entrou antes de B e C, por isso está na frente e é removida primeiro.
Resposta
A.
Um nó sem filhos recebe qual nome?
Dica
Pense na ponta de um galho.
Resolução comentada
Nó sem filhos é uma folha, pois encerra um caminho da árvore.
Resposta
Folha.
Qual representação tende a economizar memória quando cada vértice se liga a poucos outros: matriz ou lista de adjacência?
Dica
Compare guardar todas as combinações possíveis com guardar apenas as conexões existentes.
Resolução comentada
Lista de adjacência guarda apenas arestas existentes e tende a usar O(V + E). Matriz reserva O(V²) posições mesmo quando quase não há ligações.
Resposta
Lista de adjacência.
Liste dois casos de borda para uma fila vazia.
Dica
Pense em remover e consultar sem elementos.
Resolução comentada
Desenfileirar fila vazia e consultar frente de fila vazia devem ser definidos e testados; a implementação não pode acessar memória inexistente.
Resposta
Remover de fila vazia e consultar sua frente são dois casos de borda.
Qual estrutura escolher para processar tarefas na ordem de chegada: pilha ou fila?
Dica
A primeira tarefa deve sair primeiro.
Resolução comentada
Fila segue FIFO e preserva a ordem de chegada. Pilha inverteria a ordem ao remover a tarefa mais recente primeiro.
Resposta
Fila.
Intermediário (8)
Associe fila ou pilha ao mecanismo de voltar páginas no navegador e justifique a escolha.
Dica
Pergunte qual página deve aparecer primeiro ao voltar.
Resolução comentada
Usa-se uma pilha de histórico: a página visitada por último deve ser a primeira recuperada quando a pessoa usa Voltar. Em geral há uma segunda pilha para permitir Avançar.
Resposta
Pilha, porque a navegação volta na ordem inversa à das visitas.
Escreva a quantidade de elementos de uma matriz com 4 linhas e 7 colunas e diga quantas vezes dois laços aninhados a percorrem completamente.
Dica
Cada linha tem todas as colunas.
Resolução comentada
A matriz contém 4 x 7 = 28 elementos. Um laço externo de 4 iterações e outro interno de 7 executa o corpo 28 vezes.
Resposta
28 elementos e 28 execuções do corpo interno.
Por que `while (!feof(arquivo))` pode processar a última linha duas vezes ou usar um valor antigo?
Dica
Quando a função percebe que chegou ao fim?
Resolução comentada
`feof` só se torna verdadeiro depois que uma tentativa de leitura alcança o fim. O corpo entra mais uma vez antes dessa tentativa falhar. O laço deve testar o retorno de `fgets`, `fscanf` ou outra função de leitura.
Resposta
Porque EOF é marcado após uma leitura falhar; teste o retorno da leitura no laço.
Um arquivo começa com um `size_t total` e depois contém inteiros. Escreva o deslocamento para ler o elemento de índice 5 a partir do início.
Dica
Some o cabeçalho aos cinco inteiros que vêm antes do índice 5.
Resolução comentada
O deslocamento é `sizeof(size_t) + 5 * sizeof(int)`. Usar apenas `5 * sizeof(int)` cairia no lugar errado porque ignoraria os bytes do cabeçalho.
Resposta
`sizeof(size_t) + 5 * sizeof(int)`.
Um algoritmo soma todos os valores de um vetor usando apenas as variáveis `i` e `soma`. Qual é seu espaço auxiliar?
Dica
Não conte o vetor recebido; conte apenas a memória extra.
Resolução comentada
As duas variáveis ocupam quantidade fixa de memória, independente de n. Logo, o espaço auxiliar é O(1), embora o vetor de entrada ocupe O(n).
Resposta
O(1) de espaço auxiliar.
Em um vetor ordenado de 1 024 elementos, aproximadamente quantas divisões pela metade são necessárias no pior caso de busca binária?
Dica
1024 é uma potência de 2.
Resolução comentada
Como 2¹⁰ = 1024, cada divisão remove metade do intervalo até restar uma posição. A ordem é de 10 comparações, isto é, O(log n).
Resposta
Cerca de 10 divisões/comparações de nível.
Explique por que uma matriz 4 x 2 não pode ser multiplicada por uma matriz 3 x 4 nessa ordem.
Dica
Compare colunas da primeira com linhas da segunda.
Resolução comentada
A primeira tem 2 colunas, mas a segunda tem 3 linhas. Não é possível formar pares completos entre uma linha de A e uma coluna de B, portanto a regra C1 = L2 falha.
Resposta
Porque 2 != 3; as dimensões internas não são compatíveis.
Por que ordenar um vetor pode ser útil antes de realizar várias buscas nele?
Dica
Compare o custo de organizar uma vez com o de procurar muitas vezes.
Resolução comentada
Depois de ordenado, o vetor pode usar busca binária em O(log n). Quando haverá muitas consultas, o custo inicial de ordenar pode compensar a redução em cada busca.
Resposta
Porque habilita busca binária e reduz o custo de muitas consultas.
Desafio (1)
Escolha um algoritmo da disciplina e explique sua pré-condição e seu pior caso em duas frases.
Dica
Busca binária é um bom ponto de partida.
Resolução comentada
Exemplo: busca binária exige vetor ordenado; no pior caso reduz o intervalo até esvaziá-lo, realizando O(log n) comparações. A resposta pode usar outro algoritmo, desde que condição e custo sejam coerentes.
Resposta
Resposta varia; deve relacionar corretamente a pré-condição ao pior caso do algoritmo escolhido.
Resumo Geral
O que cada aula deixou como essencial, reunido.
- estrutura de dados
- TAD
- LIFO
- implementação
- vetor
- matriz
- índice
- limite
- fopen
- fclose
- fgets
- fputs
- EOF
- fread
- fwrite
- fseek
- SEEK_SET
- registro
- Big-O
- pior caso
- caso médio
- O(n)
- O(n²)
- espaço auxiliar
- busca linear
- busca binária
- interpolação
- vetor ordenado
- O(log n)
- produto escalar
- dimensões
- O(n³)
- Estabilidade
- In-place
- Custo amortizado
- Pré-condição
- Array list
- Capacidade
- Nó
- Cabeça
- Topo
- Invariável
- FIFO
- Deque
- Raiz
- Folha
- Vértice
- Aresta
- Caso de borda
- Contrato de acesso
- Recuperação ativa
- TAD descreve comportamento; implementação descreve a representação.
- A escolha da estrutura depende das operações mais frequentes.
- Vetores usam índices de 0 a n - 1.
- Uma matriz L x C tem L x C elementos.
- Sempre valide o retorno de fopen.
- Controle o laço pelo retorno de fgets, não por feof.
- fread e fwrite retornam quantos elementos processaram.
- Cabeçalhos tornam o formato interpretável ao reabrir.
- Big-O descreve crescimento, não tempo em segundos.
- Laços aninhados independentes normalmente multiplicam suas iterações.
- Busca linear não exige ordem; busca binária exige.
- Busca binária reduz o intervalo pela metade e escala em O(log n).
- A(L1 x C1) x B(L2 x C2) exige C1 = L2 e resulta em L1 x C2.
- O algoritmo clássico usa três laços e é O(n³) para matrizes quadradas.
- Ordenar reorganiza os elementos por uma chave para facilitar busca, leitura e processamento posterior.
- Estabilidade: Propriedade de preservar a ordem relativa de elementos com a mesma chave.
- In-place: Algoritmo que usa pouca memória adicional e altera a própria coleção.
- A atividade extra consolida a relação entre dados ordenados, algoritmo de ordenação e busca eficiente.
- Custo amortizado: Custo médio de uma sequência de operações, incluindo um preparo inicial como a ordenação.
- Momento de integrar persistência em arquivos, análise de custo, busca em vetores e ordenação.
- Pré-condição: Condição necessária antes de executar um algoritmo.
- Listas representam sequências; uma array list usa vetor redimensionável para equilibrar acesso por índice e crescimento.
- Array list: Lista baseada em vetor redimensionável.
- Capacidade: Quantidade de posições alocadas, que pode ser maior que o tamanho lógico.
- Listas encadeadas guardam cada elemento em um nó ligado ao próximo, favorecendo inserções e remoções quando a posição já é conhecida.
- Nó: Unidade que contém um valor e referências para outros nós.
- Cabeça: Referência ao primeiro nó da lista.
- Pilha implementa LIFO: o último elemento inserido é o primeiro removido.
- LIFO: Last In, First Out: último a entrar, primeiro a sair.
- Topo: Única extremidade acessível para inserção e remoção.
- A prática com pilhas explora a invariável de que somente o topo pode mudar a cada operação.
- Invariável: Propriedade que deve permanecer verdadeira durante a execução do algoritmo.
- Fila usa FIFO; deque permite inserir e remover nas duas extremidades.
- FIFO: First In, First Out: primeiro a entrar, primeiro a sair.
- Deque: Double-ended queue, fila com operações nas duas pontas.
- Árvores modelam relações hierárquicas com raiz, nós, arestas e subárvores.
- Raiz: Nó sem pai, ponto inicial da árvore.
- Folha: Nó sem filhos.
- Grafos representam entidades ligadas por relações, sem exigir uma hierarquia única como árvores.
- Vértice: Entidade ou ponto do grafo.
- Aresta: Ligação entre dois vértices.
- A apresentação deve tornar explícitas a estrutura escolhida, as operações implementadas, os custos e os testes realizados.
- Caso de borda: Entrada válida extrema ou especial que frequentemente revela falhas de implementação.
- A segunda prova integra estruturas lineares e não lineares, suas operações e seus custos.
- Contrato de acesso: Regra que limita quais elementos podem ser lidos ou removidos em uma estrutura.
- A recuperação revisa decisões de estrutura, implementação em C, análise de complexidade e tratamento de casos de borda.
- Recuperação ativa: Técnica de tentar lembrar e resolver antes de consultar a resposta.
Bibliografia
Como consta no Plano de Ensino oficial da disciplina.
Básica
- VELOSO, Paulo Estruturas de Dados Rio de Janeiro: Campus, 2004.
- DROZDEK, Adam Estrutura de Dados e Algoritmos em C++ São Paulo: Cengage Learning, 2009.
- SCHILDT, Herbert C, Completo e Total 3. ed. São Paulo: Makron Book, 1997.
Complementar
- ASCENCIO, Ana F. G.; ARAUJO, Graziela S. A. Estruturas de Dados: Análise da Complexidade e Implementações em JAVA e C/C++ São Paulo: Pearson Prentice Hall, 2010.
- KERNIGHAM, Brian W.; RITCHIE, Dennis M. C a Linguagem de Programação Rio de Janeiro: Campus, 2002.
- DEITEL, H. M.; DEITEL, P. J. Como Programar em C Rio de Janeiro: LTC, 1999.
- CELES, Waldemar; CERQUEIRA, Renato; RANGEL, José Lucas Introdução a estruturas de dados: com técnicas de programação em C Rio de Janeiro: Elsevier, 2004. 294 p.
- DEITEL, M. H.; DEITEL, P. J. C++ Como Programar São Paulo: Pearson Prentice Hall, 2006.
- PREISS, Bruno R. Estrutura de Dados e Algoritmos Rio de Janeiro: Campus, 2001.
Anotações
Salvas automaticamente e independentes por disciplina.
Carregando anotações…