Upload
sergio-souza-costa
View
6.087
Download
0
Embed Size (px)
Citation preview
Pilha e Fila Dinâmica
Prof: Sergio Souza Costa
Sobre mim
Sérgio Souza CostaProfessor - UFMADoutor em Computação Aplicada (INPE)
https://sites.google.com/site/profsergiocosta/home
https://twitter.com/profsergiocosta
http://gplus.to/sergiosouzacosta
http://www.slideshare.net/skosta/presentations?order=popular
Pilha Dinâmica
• A pilha que codificamos anteriormente era estática, dado que utilizava vetores.
• Agora que já codificamos a lista encadeada, podemos utiliza-la para codificar nossa pilha dinâmica.
• Antes de prosseguir, pense como seria este código.
Pilha Dinâmica
• A estrutura da pilha é bem simples, precisando apenas de uma lista para armazenar os elementos. Como a lista é dinâmica, a pilha também é dinâmica.
typedef struct { Lista* l;} Pilha;
Pilha dinâmica
• Agora precisamos codificar o tipo abstrato lista, codificando as mesmas operações que foram codificadas para a pilha estática.– Pilha* criaPilha ();
– int pilhaVazia();
– void empilha (Pilha *p, int x);
– int desempilha();
– int topo();
– int pilhaCheia (Pilha *p); Não é necessária. Por que ?
Operações da Pilha
1. Alocamos a área de memória da pilha.
2. Inicializamos a lista da pilha com lista vazia.
3. Retornamos a pilha.
Pilha* criaPilha (){ Pilha* p =
(Pilha*)malloc (sizeof(Pilha)); p->l = Vazia(); return p;}
1.
2.
3.
Operações da pilha
• Verificar se a pilha esta vazia é verificar se a lista esta vazia.
int pilhaVazia (Pilha* p) { return p->l == Vazia();}
Operações da pilha
• Empilhar um elemento X na pilha é adicioná-lo na lista.
void empilha (Pilha *p, int x) { p->l = Cons (x, p->l);}
Operações da pilha
• Retornar o elemento do topo é retornar o elemento que está na cabeça da lista, ou seja, o último adicionado.
int topo (Pilha* p) { return primeiro(p->l);}
Operações da pilha
• A operação desempilha, além de retornar o elemento do topo da pilha, precisa removê-lo.
int desempilha (Pilha* p) { int x = topo (p); p->l = resto(p->l); return x; }
Remove o elemento da cabeça da pilha
Será que posso codificar uma fila dinâmica usando a lista encadeada que já tenho pronta? O que vocês acham ?
A fila difere da pilha pelo fato de que na pilha inserimos e removemos de uma mesma extremidade. Na fila eu insiro
em uma extremidade e remove em outra.
Então, preciso criar mais uma operação para a lista. Qual seria ?
Então, preciso criar mais uma operação para a lista. Qual seria ?
InsereFim, que irá inserir o elemento no fim da lista.
Codificando
• Adicionando a operação que insere um elemento no fim da lista.
Lista* insereFim (int x, Lista* l) { Lista* aux; if (l == Vazia()) return Cons (x, l); aux = l; while (aux ->resto != Vazia()) aux = aux ->resto; aux->resto = Cons (x, Vazia()); return l;}
Codificando
• Adicionando a operação que insere um elemento no fim da lista.
Lista* insereFim (int x, Lista* l) { Lista* aux; if (l == Vazia()) return Cons (x, l); aux = l; while (aux ->resto) aux = aux ->resto; aux->cauda = Cons (x, Vazia()); return l;}
Se minha lista é vazia, então já estou no fim da lista.
Codificando
• Adicionando a operação que insere um elemento no fim da lista.
Lista* insereFim (int x, Lista* l) { Lista* aux; if (l == Vazia()) return Cons (x, l); aux = l; while (aux ->resto) aux = aux ->resto; aux->cauda = Cons (x, Vazia()); return l;}
Ou preciso percorrer a lista até o fim.
Codificando
• Adicionando a operação que insere um elemento no fim da lista.
Lista* insereFim (int x, Lista* l) { Lista* aux; if (l == Vazia()) return Cons (x, l); aux = l; while (aux ->resto) aux = aux ->resto; aux->resto = Cons (x, Vazia()); return l;}
Então posso adicioná-lo ao fim da lista.
Não entendi muito bem, este código, ele é iterativo, os que tinha feito até então era todos recursivo.
Vou agora usar uma representação gráfica comum para lista. Ela pode te ajudar a entender este código
L
5L
5 6L
5 6L 7
5 6L 7
5 6L 7
Ponteiro nulo, representa lista vazia.
5 6L 7
Ponteiro nulo, representa lista vazia.
resto, é referido também como próximo
5 6L 7
Ponteiro nulo, representa lista vazia.
cauda, é eferido também como próximo
Adicionar no fim é adicionar um novo nó neste ponto
5 6L 7
Ponteiro nulo, representa lista vazia.
resto, referido também como próximo
Adicionar no fim é adicionar um novo nó neste ponto
Então, percorremos a lista até que o resto seja nula, ou seja, não tenha mais nó. Então adicionamos um novo nó neste ponto.
5 6L 7
Ponteiro nulo, representa lista vazia.
cauda, referido também como próximo
Adicionar no fim é adicionar um novo nó neste ponto
Então, percorremos a lista até que a cauda seja nula, ou seja, não tenha mais nó. Então adicionamos um novo nó neste ponto.
Volte ao código e releia-
o buscando entender melhor o seu funcionamento antes de
prosseguir..
Acho que agora já sei como codificar a fila dinâmica.
Codificando
• A estrutura vai ser similar a da pilha, apenas com um atributo que é a lista:
typedef struct { Lista* l;}Fila;
Codificando
• O construtor também é similar ao da pilha.
Fila* criaFila () {Fila* f =
(Fila*) malloc (sizeof(Fila));f->l = Vazia();return f;
}
Codificando
• A desenfileira é similar a desempilha.
int desenfileira (Fila* f) { int x = primeiro (f->l); f->l = resto (f->l); return x; }
Codificando
• Na enfileira chamamos a operação que insere um elemento no fim da lista.
void enfileira (Fila* f, int x) { f->l = insereFim(x,f->l);}
Experimentem todos os códigos feitos nesta aula e as atividades postadas no site.
Até logo !