Estruturas de dados fundamentais em C: lista encadeada, pilha e fila.
📖 O que você vai aprender nesta página
✅ O essencial para saber
Lista encadeada: cada nó aponta para o próximo
Pilha: último a entrar, primeiro a sair (LIFO)
Fila: primeiro a entrar, primeiro a sair (FIFO)
⭐ Leia se tiver tempo
Árvores e tabelas hash
Complexidade: O(n), O(1)
Comparação com a STL / bibliotecas padrão
O que é uma Estrutura de Dados? — Projetando Como os Dados são Organizados
Uma estrutura de dados define como os dados são dispostos na memória e como você trabalha com eles. Arrays são em si uma estrutura de dados, mas várias situações tornam o uso exclusivo de arrays complicado.
Limitações de arrays
Inserção no meio/início lenta
Inserir perto do início força todo elemento seguinte a deslocar. Com um milhão de itens, são um milhão de deslocamentos.
Tamanho fixo
O tamanho fica travado na hora da declaração, o que torna dados que crescem e encolhem difíceis de lidar (malloc ajuda, mas é trabalho extra).
Estruturas de dados comuns
Estrutura
Característica
Exemplo de uso
Lista encadeada
Nós ligados por ponteiros; inserção/remoção rápida
Dados ordenados com inserção/remoção frequente
Pilha
Último a entrar, primeiro a sair (LIFO)
Chamadas de função, histórico de Desfazer
Fila
Primeiro a entrar, primeiro a sair (FIFO)
Fila de impressão, agendamento de tarefas
Todas estas são construídas a partir de structs, ponteiros e malloc. Esta aula junta tudo que aprendemos até aqui!
Lista Encadeada — Uma Cadeia Ligada por Ponteiros
Uma lista encadeada é uma sequência em que cada elemento (um nó) guarda algum dado mais um ponteiro para o próximo nó.
Definição do nó
typedefstructNode {
int data; // o dado armazenadostructNode *next; // ponteiro para o próximo nó
} Node;
Imagem na memória
10
next→
→
20
next→
→
30
next→
→
NULL
Operações principais
// (1) Criar um nóNode* createNode(int val) {
Node *n = malloc(sizeof(Node));
n->data = val;
n->next = NULL;
return n;
}
// (2) Inserir no início (O(1) — rápido!)voidpushFront(Node **head, int val) {
Node *n = createNode(val);
n->next = *head; // next do novo nó = head antigo
*head = n; // head agora aponta para o novo nó
}
// (3) Imprimir todos os elementosvoidprintList(Node *head) {
for (Node *p = head; p != NULL; p = p->next)
printf("%d → ", p->data);
printf("NULL\n");
}
// (4) Liberar a memória (esquecer = vazamento!)voidfreeList(Node *head) {
while (head) {
Node *tmp = head->next;
free(head);
head = tmp;
}
}
Inserção no início
O(1) — muito rápido
Busca
O(n) — percorre desde o head
Vs. arrays
Sem acesso por índice; acesso aleatório não é o forte.
Pilha — Último a Entrar, Primeiro a Sair (LIFO)
Uma pilha remove primeiro o item mais recentemente empilhado. Pense em empilhar pratos. A pilha de chamadas que rastreia chamadas de função funciona do mesmo jeito.
Visualização de pilha
10
20
30
← TOPO (itens saem por aqui)
// push: adiciona no topovoidpush(Node **top, int val) {
Node *n = createNode(val);
n->next = *top;
*top = n;
}
// pop: remove do topointpop(Node **top) {
if (*top == NULL) return -1;
Node *tmp = *top;
int val = tmp->data;
*top = tmp->next;
free(tmp);
return val;
}
Exemplos do dia a dia: o botão Voltar do navegador, Ctrl+Z (Desfazer) e a pilha de chamadas que rastreia chamadas de função — todos usam uma pilha por baixo dos panos.
Fila — Primeiro a Entrar, Primeiro a Sair (FIFO)
Uma fila remove itens na mesma ordem em que entraram — igual a uma fila de caixa.
Visualização de fila
Sai ←
10
20
30
→ Entra
// enqueue: adiciona na caudavoidenqueue(Node **head, Node **tail, int val) {
Node *n = createNode(val);
if (*tail) (*tail)->next = n;
else *head = n;
*tail = n;
}
// dequeue: remove da cabeçaintdequeue(Node **head, Node **tail) {
if (!*head) return -1;
Node *tmp = *head;
int val = tmp->data;
*head = tmp->next;
if (!*head) *tail = NULL;
free(tmp);
return val;
}
Exemplos do dia a dia: filas de impressão, escalonadores de tarefas do SO e ordenação de mensagens de chat.
Array vs Lista encadeada vs Pilha vs Fila
Operação
Array
Lista encadeada
Pilha
Fila
Inserir no início
O(n)
O(1)
—
—
Acrescentar no fim
O(1)
O(1)*
O(1)
O(1)
Acesso aleatório
O(1)
O(n)
—
—
Inserir no meio
O(n)
O(1)†
—
—
* com um ponteiro de cauda. † quando o ponto de inserção é conhecido.
Demo de Lista Encadeada
Use os botões para adicionar e remover elementos de uma lista encadeada e veja a estrutura atualizar em tempo real.