<Direto ao Ponto 45> As Estruturas de Dados
- #Informática Básica
Artigos desta série: ( < ) Anterior | Índice | Seguinte ( > )
Olá, dev!
Este é mais um artigo da série DIRETO AO PONTO, que eu estou escrevendo para a DIO. Ele vai tratar das estruturas de dados, uma das bases essenciais da programação.
Sumário
1. Introdução
2. A representação de dados nos programas
3. As estruturas de dados mais comuns
4. Considerações finais
5. Referências
1 – Introdução
Eu criei a série de artigos DIRETO AO PONTO com o objetivo de apresentar, de forma simples e direta, conhecimentos básicos da programação e de computação, principalmente, para os iniciantes.
Aqui, são tratados de temas como lógica de programação, linguagens, hardware dos computadores, história da computação e assuntos relacionados à plataforma da DIO, como a escrita de artigos e os desafios de código.
Neste artigo, eu vou falar sobre as estruturas de dados, ou como a programação precisa de organizações maia complexas de dados para representar as diversas formas de se implementar algoritmos avançados e complexos.
A programação se baseia nas variáveis e nos comandos de fluxo da execução do programa. O fluxo é determinado considerado pelos algoritmos, já as variáveis estão mais ligadas à implementação do algoritmo, seja com os tipos básicos oferecidos pelas linguagens ou por estruturas mais complexas, direcionadas para aplicações mais específicas ou avançadas.
As linguagens de programação oferecem alguns tipos de dados básicos primitivos para armazenar números, caracteres e dados lógicos.
Programas maiores e mais complexos não podem ser implementados apenas usando os tipos básicos de dados oferecidos pelas linguagens.
Por isso, as linguagens também costumam oferecer tipos de dados complexos, conhecidos como estruturas de dados, para representar (e implementar) modelos de aplicações complexas.
Vamos ver quais são as principais estruturas de dados oferecidas pelas linguagens e como elas são manipuladas.
2 – A representação de dados nos programas
Um programa de computador é um conjunto de instruções que são executadas sequencialmente para resolver um problema.
Um problema real precisa ser modelado para poder ser codificado por alguma linguagem de programação e virar um programa.
O modelo deve envolver a criação de um algoritmo que definirá os passos a serem seguidos na solução do problema (ou na criação de uma aplicação).
Em um artigo anterior, eu disse aqui que a programação se baseia nas variáveis e nos comandos de fluxo da execução do programa. A definição do fluxo segue o que o algoritmo determinar.
Já as variáveis que serão usadas no programa determinam como as informações que representam o modelo serão manipuladas pelo programa.
Todas as linguagens de programação oferecem vários tipos de dados básicos primitivos (nativos), que permitem armazenar dados básicos como números inteiros e reais, caracteres, dados lógicos (verdadeiro e falso).
No entanto, algumas aplicações precisam representar informações complexas, que não podem ser representadas por estes dados básicos.
Para estas representações, as linguagens oferecem alguns tipos de dados complexos, conhecidos como estruturas de dados.
As estruturas de dados são fundamentais na programação porque elas determinam como os dados são organizados, armazenados e manipulados em um programa.
Além disso, a escolha correta de uma estrutura de dados pode melhorar significativamente a eficiência e o desempenho de um programa.
Algumas estruturas de dados são adequadas para um tipo de aplicação enquanto outras são mais indicadas para outros tipos de aplicação.
As linguagens de programação podem oferecer vários tipos diferentes de estruturas de dados, algumas nativamente, inclusive oferecendo funções e métodos para manipulá-las, outras vezes, por meio da importação de bibliotecas, classes e módulos externos.
As estruturas de dados mais comuns são:
· Vetores;
· Cadeias de caracteres (strings);
· Matrizes;
· Pilhas;
· Filas;
· Listas;
· Árvores;
· Grafos.
Existem outros tipos, como tabelas hash e heaps (árvores para controle de prioridade), mas só vamos considerar estas listadas acima, com suas variações (como strings, cadeias de caracteres, dicionários e conjuntos), que podem ser simuladas por algumas das estruturas listadas.
Inicialmente, vamos ver uma estruturas de dados complexa (e geral) oferecida nativamente por alguma linguagem.
Estrutura para dados heterogêneos – algumas linguagens oferecem uma estrutura que pode juntar dados como inteiros, reais, cadeias de caracteres e outros tipos primitivos em um bloco só.
Por exemplo, a linguagem C oferece struct, que permite criar, por exemplo, um bloco com um conjunto de dados, misturando vários tipos de dados primitivos, como no exemplo abaixo, que armazena dados pessoais:
A implementação e uso de uma estrutura acima é mostrada abaixo, na linguagem C:
#include <stdio.h>
// Definindo a estrutura
struct Pessoa {
char nome[50];
int idade;
float altura;
char cpf[15];
};
int main() {
// Criando e inicializando uma variável do tipo Pessoa
struct Pessoa pessoa1 = {"Fernando Araujo", 620, 1.85, "123.456.789-00"};
// Acessando os dados da pessoa e mostrando
printf("Nome: %s\n", pessoa1.nome);
printf("Idade: %d\n", pessoa1.idade);
printf("Altura: %.2f\n", pessoa1.altura);
printf("CPF: %s\n", pessoa1.cpf);
return 0;
}
Note como a definição e o uso de uma struct se parecem com uma classe, da programação orientada a objetos, criada anos depois.
3 – As estruturas de dados mais comuns
As estruturas de dados determinam como os dados são organizados, armazenados e manipulados em um programa.
Escolher e utilizar a estrutura de dados correta é um dos passos mais importantes para garantir que o programa funcione corretamente, de forma rápida e eficiente.
Existe um compromisso entre a escolha do algoritmo para uma aplicação e a estrutura de dados escolhida. A escolha de um pode impactar na escolha do outro.
Por exemplo, se uma aplicação apresenta uma lógica hierárquica (árvore genealógica, por exemplo), a escolha de uma estrutura de dados de árvore facilitaria a implementação do algoritmo. Já a escolha por uma estrutura de dados de lista dificultaria a implementação.
Da mesma forma, se a aplicação usar recursividade, a escolha de uma árvore pode não resultar na estrutura mais adequada para implementá-la, quando seria melhor usar uma pilha.
Por exemplo, a escolha de estruturas de dados adequadas permite a execução de operações básicas (inserção, busca e remoção) de forma mais rápida.
Esta escolha também pode tornar a implementação de algoritmos mais intuitiva e eficiente, principalmente para algoritmos complexos, que dependem de estruturas de dados específicas.
Usar estruturas de dados apropriadas pode simplificar o código, tornando-o mais legível, manutenível e fácil de depurar. Além disso, esta escolha ainda pode resultar em melhoria na modelagem do problema, eficiência, desempenho, escalabilidade do programa.
Finalmente, elas podem tornar muito mais eficiente a implementação de algoritmos complexos, que dependem de estruturas de dados complexas, e de programas que lidam com grande quantidade de dados, como é comum hoje na área de Ciência de Dados e de Inteligência Artificial.
A seguir, são listadas as principais Estruturas de Dados:
· Vetores (Arrays unidimensionais) - Estrutura linear que armazena elementos em posições consecutivas de memória. Usado em listas de itens, tabelas, buffers etc.
· Matrizes (Arrays multidimensionais - Estrutura armazenada como um vetor bidimensional, dependendo de uma regra para organização das linhas e colunas. Usado em tabelas, imagens,
· Sequência (ou cadeias) de caracteres (Strings) - Estrutura armazenada como um vetor, ocupando posições consecutivas de memória. Usado para entrada e saída de dados, processamento de textos, armazenamento de dados.
· Listas Ligadas (ou encadeadas) (“Linked Lists”) - Conjunto de elementos chamados "nós", onde cada nó contém um valor e um ponteiro para o próximo nó. Usado na implementação de filas e pilhas.
· Pilhas (Stacks) - Estrutura do tipo LIFO (”Last In, First Out”), onde o último elemento inserido é o primeiro a ser removido. Usado em chamadas de funções, algoritmos recursivos e para desfazer ações em programas.
· Filas (Queues) - Estrutura do tipo FIFO (“First In, First Out”), onde o primeiro elemento inserido é o primeiro a ser removido. Usado em processamento de tarefas e sistemas de espera.
· Árvores (Trees) - Estrutura hierárquica composta por nós, onde um nó raiz possui "filhos" e folhas. Usado em bancos de dados, árvores de decisão, hierarquias.
· Grafos (Graphs) - Estrutura composta por vértices (nós) e arestas (conexões), representando relacionamentos entre pares de elementos. Usado em redes sociais, rotas, algoritmos de busca.
Cada linguagem de programação oferece um conjunto de estruturas de dados, que podem variar de simples arrays e listas a estruturas mais complexas, como árvores e grafos.
Abaixo, segue uma lista das estruturas implementadas por diversas linguagens:
· Lista: Python, C++, C#, Java, Kotlin
· Vetor: Python, C, C++, C#, Java, Javascript, Kotlin
· String: Python, C, C++, C#, Java, Javascript, Kotlin
· Pilha: C++, C#, Java, Kotlin
· Fila: C++, C#, Java
· Árvore: Java
· Grafo: nenhuma das linguagens pesquisadas (listadas para Vetor) apresenta uma estrutura específica para grafo.
4 – Considerações finais
Este é mais um artigo da série DIRETO AO PONTO, que eu estou escrevendo para a DIO. Neste artigo eu tratei das estruturas de dados.
As linguagens de programação oferecem primitivamente vários tipos de dados básicos para armazenar números, caracteres, e dados lógicos.
Programas maiores e mais complexos precisam de dados complexos, conhecidos como estruturas de dados, para representar modelos de aplicações complexas. Existem vários tipos de estruturas de dados mais avançadas que permitem uma implementação mais adequada para programas e algoritmos mais complexos.
A maioria das linguagens de programação oferece vários tipos de dados assim, como vetores, matrizes, cadeia de caracteres, listas, pilhas, filas e árvores. Este artigo procurou dar uma visão geral destas estruturas mais comuns.
No próximo artigo, eu vou começar a detalhar estas estruturas listadas acima, começando pelos vetores.
5 – Referências
Praticamente todo o conteúdo deste artigo foi tirado do que eu aprendi (e me lembro) sobre o assunto desde o início da minha carreira como programador, desde os anos 80 até agora.
Para a elaboração da lista de tipos de estruturas de dados oferecidas por algumas linguagens, eu consultei as ferramentas ChatGPT e Copilot.
Artigos desta série: ( < ) Anterior | Índice | Seguinte ( > )