Estrutura de Dados - Módulo II: Registros e Vetores de Registros

Prof. William Mendes

📚 Painel Teórico

📚 Conceitos Fundamentais

O que é um Registro?

Um registro (struct) é uma estrutura de dados heterogênea que permite agrupar diferentes tipos de dados relacionados sob um único nome, formando uma unidade lógica coesa.

Vetor vs Vetor de Registros

Analogia: Pense em uma planilha - cada linha é um registro, cada coluna é um campo. Um vetor simples seria apenas uma coluna, enquanto um vetor de registros é a planilha completa.

Boas Práticas

  • Nomeação clara: Use nomes descritivos para entidades e atributos
  • Modularização: Separe responsabilidades (validação, CRUD, UI)
  • Validação: Sempre valide tipos e restrições

Quando usar Registros?

Use registros quando precisar agrupar dados relacionados que pertencem logicamente à mesma entidade, em vez de usar múltiplas variáveis ou vetores separados.

A. Designer de Registro

Atributos:

Nome Tipo Restrições Ações

💡 Dicas Contextuais

Bem-vindo ao Simulador!

Comece definindo uma entidade no simulador abaixo. Um registro é uma estrutura que agrupa dados heterogêneos (diferentes tipos) sob um único nome.

📋 Registros (Structs)

3.1. Estrutura e Componentes

Um registro é composto por um conjunto de campos (também chamados de membros ou atributos), onde cada campo possui um nome único e um tipo de dado específico. A beleza dos registros reside na sua capacidade de combinar dados de naturezas distintas em uma única entidade.

Características dos Registros:

  • Heterogeneidade: Permitem armazenar dados de diferentes tipos em uma única estrutura.
  • Organização Lógica: Agrupam informações que pertencem logicamente a uma mesma entidade.
  • Acesso por Nome: Os campos são acessados pelo seu nome, melhorando a clareza do código.

3.2. Exemplo de Registro

Vamos considerar um exemplo prático para ilustrar o conceito de registro. Suponha que queremos representar as informações de um estudante:

Exemplos de Código:

Registro Estudante:
    nome: cadeia
    matricula: inteiro
    curso: cadeia
    media_geral: real
    data_nascimento: data

// Declaração e uso
var meu_estudante: Estudante
meu_estudante.nome ← "Maria Silva"
meu_estudante.matricula ← 12345
meu_estudante.curso ← "Engenharia de Software"
meu_estudante.media_geral ← 8.75
meu_estudante.data_nascimento ← "2003-05-10"
                            
from dataclasses import dataclass
from datetime import date

@dataclass
class Estudante:
    nome: str
    matricula: int
    curso: str
    media_geral: float
    data_nascimento: date

# Declaração e uso
meu_estudante = Estudante(
    nome="Maria Silva",
    matricula=12345,
    curso="Engenharia de Software",
    media_geral=8.75,
    data_nascimento=date(2003, 5, 10)
)

print(f"Nome: {meu_estudante.nome}")
print(f"Matrícula: {meu_estudante.matricula}")
                            
import java.time.LocalDate;

public class Estudante {
    private String nome;
    private int matricula;
    private String curso;
    private double mediaGeral;
    private LocalDate dataNascimento;
    
    // Construtor
    public Estudante(String nome, int matricula, String curso, 
                    double mediaGeral, LocalDate dataNascimento) {
        this.nome = nome;
        this.matricula = matricula;
        this.curso = curso;
        this.mediaGeral = mediaGeral;
        this.dataNascimento = dataNascimento;
    }
    
    // Getters e Setters
    public String getNome() { return nome; }
    public void setNome(String nome) { this.nome = nome; }
    // ... outros getters e setters
}

// Uso
Estudante meuEstudante = new Estudante(
    "Maria Silva", 12345, "Engenharia de Software", 
    8.75, LocalDate.of(2003, 5, 10)
);
                            
#include <stdio.h>
#include <string.h>

struct Estudante {
    char nome[100];
    int matricula;
    char curso[100];
    float media_geral;
    char data_nascimento[11]; // formato: YYYY-MM-DD
};

int main() {
    struct Estudante meu_estudante;
    
    strcpy(meu_estudante.nome, "Maria Silva");
    meu_estudante.matricula = 12345;
    strcpy(meu_estudante.curso, "Engenharia de Software");
    meu_estudante.media_geral = 8.75;
    strcpy(meu_estudante.data_nascimento, "2003-05-10");
    
    printf("Nome: %s\n", meu_estudante.nome);
    printf("Matrícula: %d\n", meu_estudante.matricula);
    printf("Curso: %s\n", meu_estudante.curso);
    printf("Média: %.2f\n", meu_estudante.media_geral);
    
    return 0;
}
                            

3.3. Aplicações e Importância

🗄️ Bancos de Dados

Representam linhas em tabelas, onde cada campo do registro corresponde a uma coluna da tabela.

🎯 Programação Orientada a Objetos

São a base para a criação de classes e objetos, onde os campos do registro se tornam os atributos da classe.

🔗 Estruturas Complexas

Podem ser combinados com outras estruturas, como vetores de registros ou listas encadeadas.

🔄 Troca de Dados

São ideais para empacotar informações que precisam ser passadas entre diferentes partes de um programa.

📊 Vetores de Registros

A combinação de vetores e registros é uma técnica poderosa para organizar coleções de dados complexos. Um vetor de registros é essencialmente um array onde cada elemento é um registro, permitindo armazenar múltiplas instâncias de uma estrutura de dados heterogênea.

Operações Comuns

  • Inserção: Adicionar um novo registro ao vetor.
  • Busca: Encontrar um registro específico com base no valor de um de seus campos.
  • Remoção: Excluir um registro do vetor.
  • Atualização: Modificar os valores dos campos de um registro existente.

Aplicações

💼 Sistemas de Gerenciamento

Para armazenar e manipular coleções de objetos ou entidades.

🏢 Aplicações Empresariais

Gerenciamento de clientes, produtos, pedidos, etc.

🎮 Simulações

Modelagem de múltiplos agentes ou elementos com propriedades complexas.

Exemplos de Código:

// Declaração do vetor de registros
var estudantes: vetor[1..100] de Estudante
var total_estudantes: inteiro ← 0

// Adicionando estudantes
total_estudantes ← total_estudantes + 1
estudantes[total_estudantes].nome ← "Maria Silva"
estudantes[total_estudantes].matricula ← 12345
estudantes[total_estudantes].curso ← "Eng. Software"
estudantes[total_estudantes].media_geral ← 8.75

total_estudantes ← total_estudantes + 1
estudantes[total_estudantes].nome ← "João Souza"
estudantes[total_estudantes].matricula ← 67890
estudantes[total_estudantes].curso ← "Ciência da Computação"
estudantes[total_estudantes].media_geral ← 9.2

// Buscar estudante por matrícula
para i de 1 até total_estudantes faça
    se estudantes[i].matricula = 12345 então
        escreva("Encontrado: ", estudantes[i].nome)
    fim_se
fim_para
                            
from dataclasses import dataclass
from datetime import date
from typing import List

@dataclass
class Estudante:
    nome: str
    matricula: int
    curso: str
    media_geral: float
    data_nascimento: date

# Vetor de registros
estudantes: List[Estudante] = []

# Adicionando estudantes
estudantes.append(Estudante(
    nome="Maria Silva",
    matricula=12345,
    curso="Engenharia de Software",
    media_geral=8.75,
    data_nascimento=date(2003, 5, 10)
))

estudantes.append(Estudante(
    nome="João Souza",
    matricula=67890,
    curso="Ciência da Computação",
    media_geral=9.2,
    data_nascimento=date(2002, 11, 20)
))

# Buscar estudante por matrícula
def buscar_por_matricula(matricula: int) -> Estudante:
    for estudante in estudantes:
        if estudante.matricula == matricula:
            return estudante
    return None

# Listar todos ordenados por média
estudantes_ordenados = sorted(estudantes, 
                            key=lambda x: x.media_geral, 
                            reverse=True)

for estudante in estudantes_ordenados:
    print(f"{estudante.nome}: {estudante.media_geral}")
                            
import java.time.LocalDate;
import java.util.*;

public class GerenciadorEstudantes {
    private List<Estudante> estudantes;
    
    public GerenciadorEstudantes() {
        this.estudantes = new ArrayList<>();
    }
    
    // Adicionar estudante
    public void adicionarEstudante(Estudante estudante) {
        estudantes.add(estudante);
    }
    
    // Buscar por matrícula
    public Estudante buscarPorMatricula(int matricula) {
        for (Estudante estudante : estudantes) {
            if (estudante.getMatricula() == matricula) {
                return estudante;
            }
        }
        return null;
    }
    
    // Listar ordenados por média
    public List<Estudante> listarPorMedia() {
        List<Estudante> copia = new ArrayList<>(estudantes);
        copia.sort((e1, e2) -> 
            Double.compare(e2.getMediaGeral(), e1.getMediaGeral()));
        return copia;
    }
    
    // Remover estudante
    public boolean removerPorMatricula(int matricula) {
        return estudantes.removeIf(e -> e.getMatricula() == matricula);
    }
    
    public static void main(String[] args) {
        GerenciadorEstudantes gerenciador = new GerenciadorEstudantes();
        
        gerenciador.adicionarEstudante(new Estudante(
            "Maria Silva", 12345, "Eng. Software", 8.75,
            LocalDate.of(2003, 5, 10)
        ));
        
        gerenciador.adicionarEstudante(new Estudante(
            "João Souza", 67890, "Ciência da Computação", 9.2,
            LocalDate.of(2002, 11, 20)
        ));
        
        // Buscar e exibir
        Estudante encontrado = gerenciador.buscarPorMatricula(12345);
        if (encontrado != null) {
            System.out.println("Encontrado: " + encontrado.getNome());
        }
    }
}
                            
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_ESTUDANTES 100

struct Estudante {
    char nome[100];
    int matricula;
    char curso[100];
    float media_geral;
    char data_nascimento[11];
};

struct VetorEstudantes {
    struct Estudante estudantes[MAX_ESTUDANTES];
    int total;
};

// Adicionar estudante
void adicionar_estudante(struct VetorEstudantes* vetor, 
                        struct Estudante estudante) {
    if (vetor->total < MAX_ESTUDANTES) {
        vetor->estudantes[vetor->total] = estudante;
        vetor->total++;
    }
}

// Buscar por matrícula
struct Estudante* buscar_por_matricula(struct VetorEstudantes* vetor, 
                                      int matricula) {
    for (int i = 0; i < vetor->total; i++) {
        if (vetor->estudantes[i].matricula == matricula) {
            return &vetor->estudantes[i];
        }
    }
    return NULL;
}

// Listar todos
void listar_estudantes(struct VetorEstudantes* vetor) {
    printf("Lista de Estudantes:\n");
    for (int i = 0; i < vetor->total; i++) {
        printf("%d. %s (Mat: %d) - Média: %.2f\n", 
               i+1, 
               vetor->estudantes[i].nome,
               vetor->estudantes[i].matricula,
               vetor->estudantes[i].media_geral);
    }
}

int main() {
    struct VetorEstudantes vetor = {.total = 0};
    
    // Criar estudantes
    struct Estudante e1 = {"Maria Silva", 12345, "Eng. Software", 8.75, "2003-05-10"};
    struct Estudante e2 = {"João Souza", 67890, "Ciência da Computação", 9.2, "2002-11-20"};
    
    // Adicionar ao vetor
    adicionar_estudante(&vetor, e1);
    adicionar_estudante(&vetor, e2);
    
    // Listar todos
    listar_estudantes(&vetor);
    
    // Buscar específico
    struct Estudante* encontrado = buscar_por_matricula(&vetor, 12345);
    if (encontrado != NULL) {
        printf("Encontrado: %s\n", encontrado->nome);
    }
    
    return 0;
}
                            

📖 Bibliografia

  • SAGAH. Estrutura de Dados. Porto Alegre: SAGAH, 2018.
  • CORMEN, T. H. et al. Algoritmos: Teoria e Prática. 3. ed. Rio de Janeiro: Elsevier, 2012.
  • ZIVIANI, N. Projeto de Algoritmos com Implementações em Pascal e C. 3. ed. São Paulo: Cengage Learning, 2011.
  • GOODRICH, M. T.; TAMASSIA, R. Estruturas de Dados e Algoritmos em Java. 5. ed. Porto Alegre: Bookman, 2013.
  • SZWARCFITER, J. L.; MARKENZON, L. Estruturas de Dados e seus Algoritmos. 3. ed. Rio de Janeiro: LTC, 2010.