STRUCT
Estrutura de Dados
Contextualizando…
Contextualizando…
Qual o problema deste código?
São duas funções que recebem os mesmos
parâmetros.
Estamos passando o mesmo argumento duas
vezes.
Mas é apenas um livro e estamos passando 3
dados.
Contextualizando…
E se… quisermos passar mais informações sobre o
livro? Como por exemplo: número de páginas.
É só adicionar mais um parâmetro nas duas
funções.
E se… tivéssemos 100 funções ?
Struct
Uma struct (abreviação de "structure") é um tipo de
dado definido que permite agrupar diferentes
variáveis (de tipos possivelmente diferentes) sob um
único nome.
Isso torna o código mais legível, organizado e fácil
de gerenciar, especialmente quando você lida com
entidades complexas que possuem múltiplos atributos.
Struct
São úteis:
Representar registros: Como informações de
clientes, produtos, alunos, etc.
Passar múltiplos valores como um
único argumento para funções.
Struct
São úteis:
Retornar múltiplos valores de uma função (usando
ponteiros para structs).
Implementar estruturas de dados mais complexas:
Como listas ligadas, árvores e grafos.
Struct
Sintaxe:
Struct
Sintaxe:
struct Pessoa declara uma nova estrutura chamada
Pessoa.
Dentro das chaves, definimos três membros:
● char nome[50]: um array de caracteres para
armazenar o nome (string).
● int idade: um inteiro para armazenar a idade.
● float altura: um ponto flutuante para armazenar
a altura.
Struct
Depois de definir a estrutura, você pode declarar
variáveis desse novo tipo struct Pessoa
Struct
Acessar os membros de uma struct
Struct
Inicializar a struct na declaração:
Struct
Para simplificar e
evitar usar struct
toda vez, pode-se
usar o typedef
Struct
Struct
aninhada:
Struct
Struct aninhada:
Struct
Ponteiros para Struct
Para acessar os membros de uma struct através de um
ponteiro, você usa o operador seta (->).
Struct
Ponteiros para Struct
Outra forma de acessar os membros de uma struct
através de um ponteiro:
Struct
Structs como parâmetros de funções (valor)
Struct
Structs como parâmetros de funções (referência)
Vetor de Struct
Determina uma struct Pessoa com as informações
pessoais
Vetor de Struct
Estrutura que representa o vetor de Pessoas,
incluindo um contador
Vetor de Struct
Para inicializar uma lista sequencial já criada
pelo usuário, só precisamos colocar o valor 0
(zero) no número de elementos válidos
Vetor de Struct
Para saber o tamanho do vetor basta retornar o o
número de elementos do vetor
Vetor de Struct
Inserir na última posição
Vetor de Struct
Inserir em uma posição específica
Vetor de Struct
Busca um elemento específico
Vetor de Struct
Exclusão de um elemento específico
Vetor de Struct
Exclusão de um elemento na posição específica
Vetor de Struct
Exibição
Colocando em prática
Colocando em prática
Colocando em prática
Colocando em prática
Colocando em prática
Colocando em prática
Colocando em prática
Colocando em prática
Colocando em prática
Colocando em prática
Colocando em prática
Colocando em prática
Colocando em prática
Saída:
Complexidade de Algoritmo
A análise de algoritmo busca responder à seguinte
pergunta: podemos fazer um algoritmo mais
eficiente?
Em programação, podemos resolver um problema de
diferentes formas, ou seja, é possível usar
algoritmos diferentes para resolver o mesmo
problema.
Complexidade de Algoritmo
Algoritmos com capacidade de resolver o mesmo
problema, podem não ter a mesma eficiência.
Essas diferenças podem ser irrelevantes em listas
pequenas ou podem crescer proporcionalmente com o
número de elementos processados
Para comparar a eficiência dos algoritmos foi
criada uma medida chamada complexidade de
algoritmo
Complexidade de Algoritmo
A complexidade computacional indica o custo ao se
aplicar um algoritmo, sendo:
custo = memória + tempo
Complexidade de Algoritmo
A análise assintótica é uma técnica matemática
usada para descrever o comportamento limite de
uma função quando o argumento tende para um valor
particular ou para o infinito.
Usamos a análise assintótica para descrever como
o tempo de execução (ou espaço) de um algoritmo
se comporta à medida que o tamanho da entrada (n)
se torna muito grande (tende ao infinito).
Complexidade de Algoritmo
Análise assintótica nos permite:
● Ignorar detalhes de implementação:
independentemente da linguagem de programação, do
hardware ou de outras otimizações de baixo nível.
● Comparar a eficiência de algoritmos: Podemos
comparar diferentes algoritmos para o mesmo
problema e determinar qual deles será mais
eficiente para entradas grandes.
● Prever o escalonamento
Complexidade de Algoritmo
A notação Big O é uma das notações assintóticas
mais comumente usadas para descrever o limite
superior (pior caso) do tempo de execução (ou
espaço) de um algoritmo.
Complexidade de Algoritmo
Exemplo Big O:
Imagine que você tem um vetor com n inteiros:
● O algoritmo percorre o vetor todo:
ele faz n operações → O(n)
● O algoritmo só faz um cálculo fixo:
ele faz sempre a mesma coisa → O(1)
● O algoritmo compara cada item com todos os outros
(dois for aninhados):
ele faz cerca de n * n comparações → O(n²)
Complexidade de Algoritmo
Exemplos Comuns de Notação Big O:
O(1) (Tempo Constante): O tempo de execução é
independente do tamanho da entrada.
● Exemplo: Acessar um elemento em um array pelo seu
índice.
Complexidade de Algoritmo
Exemplos Comuns de Notação Big O:
O(log n) (Tempo Logarítmico): O tempo de execução
cresce logaritmicamente com o tamanho da entrada.
Geralmente ocorre em algoritmos que dividem o
problema em partes menores a cada passo.
● Exemplo: Busca binária em um array ordenado.
Complexidade de Algoritmo
Exemplos Comuns de Notação Big O:
O(n) (Tempo Linear): O tempo de execução cresce
diretamente proporcional ao tamanho da entrada.
● Exemplo: Percorrer todos os elementos de um
array.
Complexidade de Algoritmo
Exemplos Comuns de Notação Big O:
O(n log n) (Tempo Linear-Logarítmico ou "n log
n"): Uma combinação de tempo linear e
logarítmico. Frequentemente encontrado em
algoritmos de ordenação eficientes.
● Exemplo: Merge Sort, Heap Sort.
Complexidade de Algoritmo
Exemplos Comuns de Notação Big O:
O(n2) (Tempo Quadrático): O tempo de execução
cresce proporcional ao quadrado do tamanho da
entrada. Comum em algoritmos com dois loops
aninhados que percorrem todos os pares de
elementos.
● Exemplo: Bubble Sort, Selection Sort.
Complexidade de Algoritmo
Exemplos Comuns de Notação Big O:
O(2n) (Tempo Exponencial): O tempo de execução
dobra com cada incremento no tamanho da
entrada. Geralmente indica algoritmos muito
ineficientes para entradas grandes.
● Exemplo: Tentar todas as combinações possíveis
em um conjunto.
Complexidade de Algoritmo
Exemplos Comuns de Notação Big O:
O(n!) (Tempo Fatorial): O tempo de execução
cresce fatorialmente com o tamanho da entrada.
Extremamente ineficiente para qualquer entrada
moderadamente grande.
● Exemplo: Calcular todas as permutações
possíveis de um conjunto.
●
Complexidade de Algoritmo
Exemplos Comuns de Notação Big O:
inicializar O(1)
Big O - Vetor estático inserir O(1)
inserirNaPos O(n)
icao
remover O(n)
removerNaPos O(n)
icao
buscar O(n)
buscarTodos O(n)
tamanho O(1)
exibir O(n)