Estrutura de dados: tipos, custos e como escolher
Compare vetores, listas, pilhas, filas, tabelas hash, árvores e grafos. Aprenda a escolher uma estrutura de dados com um exemplo de atendimento.

Em poucas palavras
- A escolha começa pelas operações que o problema exige.
- Interface, implementação e algoritmo representam níveis diferentes.
- Custos esperados, amortizados e de pior caso não são equivalentes.
Neste artigo
Estrutura de dados é uma forma de organizar informações e definir como elas podem ser consultadas, inseridas, removidas e percorridas. Vetores, listas encadeadas, pilhas, filas, tabelas hash, árvores e grafos atendem a necessidades diferentes. A escolha depende das operações mais frequentes, do tamanho da entrada, da memória disponível e das garantias de desempenho exigidas pelo problema.
Para quem começa na graduação, decorar nomes costuma esconder a decisão mais importante: o que o programa precisa fazer com os dados? Um cadastro pesquisado por identificador pede uma análise diferente de um histórico de ações ou de uma rede de conexões. Este guia compara estruturas, apresenta custos com suas condições e desenvolve um exemplo de escolha para um sistema de atendimento.
Estrutura, tipo abstrato e algoritmo: qual é a diferença?
Um tipo abstrato de dados descreve operações e regras sem impor uma organização interna. Uma fila, por exemplo, permite inserir no fim e retirar do início, respeitando a ordem de chegada. Uma implementação concreta precisa decidir onde guardar cada elemento e como atualizar as referências. Um vetor circular e uma lista encadeada podem realizar a mesma interface de fila.
Algoritmos são procedimentos que usam essas operações para resolver um problema. Um algoritmo de busca depende da organização da coleção: percorrer uma sequência não ordenada é diferente de aproveitar uma ordenação. Classes e objetos, por sua vez, podem encapsular as estruturas. Essa relação aparece no guia de programação orientada a objetos, mas encapsular não elimina a necessidade de analisar custos.
Vetores e listas encadeadas
Em um vetor, posições podem ser acessadas diretamente por índice. Em um modelo usual de memória, localizar a posição i não exige visitar todas as anteriores. Já inserir no começo de uma sequência armazenada em vetor pode exigir deslocar elementos. Vetores dinâmicos reservam capacidade e, em determinados momentos, precisam alocar espaço maior e copiar referências ou valores.
Uma lista encadeada organiza elementos em nós conectados por referências. Para alcançar uma posição arbitrária, normalmente é preciso seguir os elos desde um ponto conhecido. Inserir depois de um nó já localizado pode exigir poucas mudanças de referência, mas encontrar esse nó tem um custo próprio. Dizer que toda inserção em lista é constante mistura essas duas etapas e produz uma comparação enganosa.
A memória também entra na decisão. Nós encadeados precisam guardar referências, enquanto um vetor reserva uma região organizada para seus elementos. O acesso à memória, as alocações e o comportamento do ambiente de execução podem influenciar o tempo observado. A análise assintótica continua útil, mas não substitui medições quando diferenças de implementação passam a ser relevantes.
| Organização | Operação favorecida | Cuidado na comparação |
|---|---|---|
| Vetor | Acesso por índice em O(1) | Inserções no meio podem deslocar O(n) elementos. |
| Vetor dinâmico | Adicionar no fim em O(1) amortizado | Uma expansão isolada pode custar O(n). |
| Lista encadeada | Inserir após um nó conhecido em O(1) | Localizar uma posição pode exigir O(n). |
| Tabela hash | Consulta por chave em O(1) esperado, sob hipóteses usuais | Colisões e redimensionamentos afetam o custo; não é garantia universal. |
| Árvore de busca balanceada | Busca ordenada em O(log n) | Uma árvore de busca sem balanceamento pode degradar para O(n). |
- Organização
- Vetor
- Operação favorecida
- Acesso por índice em O(1)
- Cuidado na comparação
- Inserções no meio podem deslocar O(n) elementos.
- Organização
- Vetor dinâmico
- Operação favorecida
- Adicionar no fim em O(1) amortizado
- Cuidado na comparação
- Uma expansão isolada pode custar O(n).
- Organização
- Lista encadeada
- Operação favorecida
- Inserir após um nó conhecido em O(1)
- Cuidado na comparação
- Localizar uma posição pode exigir O(n).
- Organização
- Tabela hash
- Operação favorecida
- Consulta por chave em O(1) esperado, sob hipóteses usuais
- Cuidado na comparação
- Colisões e redimensionamentos afetam o custo; não é garantia universal.
- Organização
- Árvore de busca balanceada
- Operação favorecida
- Busca ordenada em O(log n)
- Cuidado na comparação
- Uma árvore de busca sem balanceamento pode degradar para O(n).
Pilhas, filas e filas de prioridade
Uma pilha segue a regra de que o último elemento inserido é o primeiro retirado. Ela é adequada quando o trabalho pendente precisa ser retomado na ordem inversa, como em uma sequência controlada de desfazer ações. Uma fila comum preserva a ordem de entrada. A regra de retirada deve ser definida antes de escolher os métodos oferecidos por uma biblioteca.
Uma fila de prioridade retira elementos conforme uma prioridade, e não apenas pela chegada. Um heap binário é uma implementação frequente: mantém uma propriedade entre pais e filhos que permite consultar o extremo e reorganizar a estrutura após inserções ou remoções. Ele não deixa todos os elementos completamente ordenados. Se o programa precisa percorrer tudo em ordem, essa diferença importa.

Dicionários, árvores e grafos
Um dicionário associa chaves a valores. Uma tabela hash transforma a chave em informação útil para localizar uma região de armazenamento e precisa lidar com colisões. Uma árvore de busca organiza chaves de acordo com uma relação de ordem. Quando a tarefa inclui consultar intervalos ou obter o próximo valor em ordem, essa organização pode ser mais apropriada do que uma tabela hash.
Grafos descrevem vértices e conexões. Uma lista de adjacência registra os vizinhos de cada vértice; uma matriz de adjacência organiza a presença ou o peso de conexões por pares. A densidade da rede e as consultas frequentes orientam a escolha. Mapas e redes espaciais, como os estudados em sistemas de informação geográfica, mostram por que representar relações é diferente de simplesmente guardar uma sequência.
Exemplo: organizar um atendimento por chegada
Ao abrir um chamado, o programa cria seu registro, adiciona seu identificador à fila e atualiza o dicionário. Ao atender, retira o próximo identificador e consulta o registro. Se houver cancelamentos, será necessário definir como tratar um identificador ainda presente na fila. Essa regra de consistência faz parte do projeto; o uso de duas estruturas não resolve automaticamente a sincronização entre elas.
O exercício pode ser implementado com uma fila que tenha remoção eficiente no início. Em Python, a documentação apresenta deque como opção para operações nas extremidades. Usar repetidamente pop(0) em uma list exige deslocamentos. O ponto didático não é declarar uma linguagem vencedora, mas reconhecer que métodos com resultados semelhantes podem realizar trabalhos internos diferentes.
Como ler O(1), O(n) e O(log n)
A notação O descreve um limite assintótico de crescimento em um modelo definido. O(1) não significa execução instantânea, e O(n) não fornece um tempo em segundos. É necessário dizer o que n representa e qual operação está sendo analisada. Também convém distinguir pior caso, custo esperado e custo amortizado, pois essas expressões respondem a perguntas diferentes.
Para comparar alternativas, escreva uma carga de trabalho: quantas buscas, inserções, exclusões e travessias serão feitas? Depois considere restrições como ordem, repetição de chaves e memória. Um programa que faz uma única consulta em uma coleção pequena pode não justificar uma estrutura complexa. Já uma coleção que cresce e é pesquisada continuamente merece uma análise mais cuidadosa.
Roteiro de estudo e escolha
Da necessidade à implementação
- Descreva os dados e as operações exigidas, antes de escolher a coleção.
- Defina se precisa de ordem, acesso por índice, consulta por chave ou relações entre elementos.
- Compare os custos das operações mais frequentes, indicando as hipóteses de cada custo.
- Implemente um exemplo pequeno e teste coleção vazia, repetição, inclusão, remoção e atualização.
- Meça cargas representativas quando o desempenho real for importante e registre os limites da comparação.
Uma atividade útil é resolver o mesmo problema com duas representações e explicar cada troca. No atendimento, compare uma sequência com remoção no início e uma fila apropriada. Conte o trabalho realizado e observe o crescimento ao aumentar a entrada. Esse raciocínio une correção, complexidade e clareza do código, em vez de transformar a disciplina em um catálogo de nomes.
Perguntas frequentes
Qual é a melhor estrutura de dados?
Não existe uma escolha universal. A estrutura adequada é a que atende às operações e às restrições do problema com uma implementação compreensível. A resposta deve explicar quais operações são frequentes, que garantias são necessárias e quais custos de memória e manutenção foram aceitos.
Uma lista de Python é uma lista encadeada?
Não. A list de Python é uma sequência baseada em armazenamento dinâmico de referências, com acesso por índice. Seu nome não garante as propriedades de uma lista encadeada. Compare a documentação e os custos dos métodos antes de transferir conclusões entre linguagens ou bibliotecas.
Preciso saber programação orientada a objetos primeiro?
É possível estudar estruturas usando funções, registros e referências, sem depender inicialmente de uma abordagem orientada a objetos. Depois, interfaces e classes ajudam a encapsular implementações. Os fundamentos indispensáveis são compreender variáveis, controle de fluxo, funções e como o programa representa e modifica suas informações.
Vídeo para aprofundar
Referências
- MIT OpenCourseWare. 6.006 Introduction to Algorithms: Lecture Notes, Spring 2020. https://ocw.mit.edu/courses/6-006-introduction-to-algorithms-spring-2020/pages/lecture-notes/
- MORIN, Pat. Open Data Structures. Capítulos sobre interfaces, listas, tabelas hash, árvores e grafos. https://opendatastructures.org/newhtml/ods/latex/index.html
- Python Software Foundation. Tutorial: Estruturas de dados. https://docs.python.org/pt-br/3/tutorial/datastructures.html
- Python Software Foundation. collections: deque objects. https://docs.python.org/3/library/collections.html
Autoria
Study Mais
Continue estudando

Programação orientada a objetos: conceitos e exemplos
Entenda classes, objetos, encapsulamento, herança e polimorfismo com um exemplo de biblioteca e decisões práticas de modelagem.

Sistemas de informação geográfica: conceitos e aplicações
Entenda como os sistemas de informação geográfica integram dados, camadas e análises espaciais, com exemplo de projeto e cuidados metodológicos.

Deriva genética: mecanismo, efeito fundador e gargalo
Entenda deriva genética, frequências alélicas, efeito fundador e gargalo, com exemplos e diferenças em relação à seleção natural.
