A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Estruturas de Dados aula 3

Apresentações semelhantes


Apresentação em tema: "Estruturas de Dados aula 3"— Transcrição da apresentação:

1 Estruturas de Dados aula 3
Estruturas de Dados – aula 2 – Complexidade e Listas Ligadas Estruturas de Dados aula 3 Sistemas de Informação EaD

2 Fundamentos de Complexidade Listas Ligadas: Conceito Manipulação
Agenda desta Aula Fundamentos de Complexidade Listas Ligadas: Conceito Manipulação Análise

3 Fundamentos de Complexidade
É necessário fazer medidas de velocidade para os algoritmos Deve ser independente da tecnologia Contagem do número de operações/comandos de um programa Calcular a função em relação ao tamanho da entrada é necessário ter medidas de velocidade de um programa, independente de tecnologia. Isso se faz contando-se o número de operações realizadas pelo programa e calculando-se uma fórmula em função do tamanho da entrada.

4 Exemplo x = 1; if ( n == 0 ) n = n + 1 i = 0; while ( i < n )
i = i + 2; for( i = 0; i < n ; i++ ) for( j = 0; j < n ; j++ ) for( k = 0; k < n ; k++ ) x := x * 2

5 Análise Número de comandos: n / 2 + n3 4 + n / 2 + n3 o membro de maior crescimento é n3 então a complexidade é O( n3 )

6 Exemplo de crescimento
Exemplos de crescimento de função. Note que o exponencial cresce bastante se continuarmos o gráfico.

7 Crescimento das funções
Funções exponenciais crescem muito rápido Função logarítmica cresce devagar Em geral, procuramos obter programas cuja função seja um polinômio Toma-se o elemento de maior crescimento e usa-se a notação O O(n) – crescimento linear A função exponencial cresce muito rápido, e a logarítmica bem devagar. Em geral, busca-se funções polinomiais. A notação O se refere ao termo de maior crescimento da função.

8 Sobre a análise Analisa o pior caso Garante que o programa nunca será executado em mais tempo que o estipulado (limite superior) Em alguns programas, o caso médio (comum, não extremo) é eficiente, mas o pior caso é ruim Sempre analisaremos de forma pessimista (pior caso). Isso garante que um programa nunca será executado em mais tempo que o calculado O caso médio muitas vezes é bom, mas o caso pessimista é ruim, por esse motivo algumas pessoas criticam essa medida.

9 Nova tabela, pelo tempo de execução
16 0.016s 0.064s 0.256s 4s 1m 4s 32 0.032s 0.16s 1s 33s 46 dias 512 0.512s 9s 4m 22s 1 dia 13h séculos aqui algumas medidas. Note que no caso exponencial, mesmo com um computador um milhão de vezes mais rápido, o tempo é inviável

10 Problemas Difíceis em Computação
Existem problemas para os quais somente são conhecidos algoritmos com crescimento exponencial Exemplos: Problema da Mochila – Colocar o maior valor possível em uma mochila Caixeiro viajante – deve percorrer todas as cidades minimizando o tamanho do percurso

11 Objetivos em relação à complexidade
Construir estruturas para minimizar a complexidade dos algoritmos Na verdade, objetivo da ciência da computação em geral.

12 Estruturas dinâmicas, de tamanho flexível. Vetores – tamanho fixo
Listas Ligadas Estruturas dinâmicas, de tamanho flexível. Vetores – tamanho fixo Vantagens Uso racional da memória Tamanho flexível. Tamanho limitado pela memória do computador vamos introduzir as listas ligadas. Os vetores tem tamanho fixo, o que não traz flexibilidade. A lista traz as vantagens listadas

13 Acesso linear. Vetores – acesso aleatório Uso maior de memória
Listas Ligadas Desvantagens Acesso linear. Vetores – acesso aleatório Uso maior de memória Maior complexidade Essas são as desvantagens das listas:Acesso linear. Vetores – acesso aleatório Uso maior de memória Maior complexidade

14 Representação Gráfica
A Lista é composta por células struct Celula {   char dado[80]; struct celula *prox; } A Lista é composta por células. exibimos a declaração e representação gráfica das listas

15 Exemplo gráfico de lista
Note o ponteiro para o início da lista e o final, um ponteiro nulo indicado Pelo ponteiro cortado Note o ponteiro para o início da lista e o final, um ponteiro nulo indicado Pelo ponteiro cortado

16 Abstract Data Type – Tipo Abstrato de Dados
ADT Abstract Data Type – Tipo Abstrato de Dados Define operações que podem ser feitas com o tipo. Para as Listas: Inicialização Inclusão Exclusão Busca Percurso Um tipo abstrato de dados possui operações que podem ser feitas. No caso das listas temos as operações listadas

17 Não usar um ponteiro nulo Não perder ponteiros para as células
Inclusão Pode ser feita: No início No final Em uma posição do meio Cuidados: Não usar um ponteiro nulo Não perder ponteiros para as células Em todas as operações devemos tomar esses cuidados. Mostraremos o código correspondente e a operação sendo feita exibida de modo gráfico

18 Inclusão no início p = (struct Celula*) malloc( sizeof(struct Celula ); strcpy(p->dado, dado); p->prox = inicio; inicio = p; primeiro é criada a nova célula, apontada por “p”

19 Inclusão no início p = (struct Celula*) malloc( sizeof(struct Celula ); strcpy(p->dado, dado); p->prox = inicio; inicio = p; Inserimos o dado a ser armazenado, na figura um código

20 Inclusão no início p = (struct Celula*) malloc( sizeof(struct Celula ); strcpy(p->dado, dado); p->prox = inicio; inicio = p; Fazemos o ponteiro para o próximo elemento ser o que está no início da lista

21 Inclusão no início p = (struct Celula*) malloc( sizeof(struct Celula ); strcpy(p->dado, dado); p->prox = inicio; inicio = p; apontamos o início da lista para o novo elemento.

22 Exemplo de ordem errada
procedimento inserirInicio( var inicio: PCelula, dado: texto ) var p: PCelula; início new (p); inicio := p; p^.dado := dado; p^.prox := inicio; fim Neste exemplo, a operação indicada “perde” a lista inteira, que não poderá mais ser usada.

23 Listas Duplamente Ligadas
Na célula, além de um ponteiro para o próximo elemento, há um ponteiro para o elemento anterior Vantagens Percurso nos dois sentidos Exclusão facilitada O(1) Desvantagens Mais memória Um pouco mais complexo para manipular As listas duplamente ligadas tem um ponteiro a mais em cada célula, para o elemento anterior. Dessa forma, é possível fazer o percurso nos dois sentidos e a exclusão é facilitada. As desvantagens são o uso maior de memória e a complexidade um pouco maior

24 Célula struct Celula { char dado[80]; struct Celula * ant;
* prox; } Aqui mostramos a declaração da célula e a representação gráfica de uma célula. Note o ponteiro a mais ant.

25 Exemplo de Lista Note os ponteiros para os dois lados nas células
Aqui exibimos um exemplo de lista já pronta. Note os ponteiros para os dois lados nas células Note os ponteiros para os dois lados nas células

26 Operações São as mesmas que nas listas ligadas
Cuidados com os dois ponteiros Facilidade: podemos acessar o elemento anterior, o que não era possível As operações são as mesmas que nas listas ligadas, com o cuidado de atualizar e verificar o ponteiro para o elemento anterior. Temos agora uma facilidade que é possível voltar ao elemento anterior, o que não podia ser feito nas listas ligadas.

27 Pilhas Estrutura linear Somente o topo é visível
Primeiro a entrar, último a sair. Operações: Empilhar Desempilhar Pilha Vazia Iniciar Consultar topo A pilha é uma estrutura linear, onde somente o elemento no topo da pilha é visível, como uma pilha de pratos, de livros, etc. A regra fundamental da pilha é “primeiro a entrar, último a sair”. As operações da pilha são as listadas: empilhar, desempilhar, verificação de pilha vazia, iniciar pilha e verificação do topo da pilha

28 Operações topo 3 10 5 7 9 8 aqui exibimos uma figura representando
uma pilha de números inteiros. O elemento indicado é o topo da pilha 7 9 8

29 Operações topo 3 10 5 Não se enxerga o resto da pilha, somente o topo 7 9 8

30 Operações 3 topo 10 5 Desempilhar 7 9 8
a ação de desempilhar retira o elemento, e o elemento seguinte passa para o topo 7 9 8

31 Operações 20 topo 10 5 Empilhar 7 9 8
A ação de empilhar coloca elemento no topo. 7 9 8

32 Operações topo 20 10 5 Empilhar O novo elemento foi para o topo 7 9 8

33 Operações topo 20 10 5 Empilhar o topo antigo passa a ser oculto 7 9 8

34 Aplicação – verificação de parênteses
Aplicação de pilha – verificação de seqüência de parênteses correta Ex: Correta: ((()))()(()) Incorreta: (())) ou (() Idéia: ao abrir parênteses empilha o símbolo. Quando fechar, desempilha No final, pilha deve estar vazia Aplicação de pilha – verificação de seqüência de parênteses correta Ex: Correta: ((()))()(()) Incorreta: (())) ou (() Idéia: ao abrir parênteses empilha o símbolo. Quando fechar, desempilha No final, pilha deve estar vazia

35 Exemplo (()) no início, lemos o primeiro parênteses. como é um abertura, ele vai para o topo da pilha topo (

36 Exemplo (()) outro abre parênteses, vai novamente para a pilha ( topo (

37 Exemplo (()) ( quando vem um fecha parênteses, desempilha um elemento topo (

38 Final de seqüência, pilha vazia, ok
Exemplo (()) ( ( veio outro fecha, desempilha. Como a seqüência acabou e a pilha está vazia, a seqüência é válida topo nil Final de seqüência, pilha vazia, ok

39 Exemplo com erro (() vamos agora mostrar uma seqüência com erro. Note que falta um parênteses a fechar

40 Exemplo (() Colocamos o parênteses na pilha topo (

41 Exemplo (() Mais um elemento na pilha ( topo (

42 Final da seqüência, pilha não vazia, ERRO !
Exemplo (() ( chegamos no final da seqüência, como a pilha não está vazia, há erro topo ( Final da seqüência, pilha não vazia, ERRO !

43 Exemplo ()) Outro exemplo com erro. Colocamos o elemento na pilha topo (

44 Exemplo ()) ( Desempilha o elemento topo nil

45 Precisaria desempilhar com pilha vazia, ERRO
Exemplo ()) ( Precisaríamos desempilhar, mas a pilha está vazia, portanto há erro topo nil Precisaria desempilhar com pilha vazia, ERRO


Carregar ppt "Estruturas de Dados aula 3"

Apresentações semelhantes


Anúncios Google