Pilhas e Filas Denise Guliato Faculdade de Computao

  • Slides: 53
Download presentation
Pilhas e Filas Denise Guliato Faculdade de Computação – UFU www. facom. ufu. br/~guliato

Pilhas e Filas Denise Guliato Faculdade de Computação – UFU www. facom. ufu. br/~guliato Vários slides foram adaptados de Nina Edelwais e Renata Galante Estrutura de Dados – Série de Livros Didáticos - Informática - UFRGS

Listas lineares especiais Pilhas e filas Com disciplina restrita de organização e acesso a

Listas lineares especiais Pilhas e filas Com disciplina restrita de organização e acesso a seus nodos Disciplina restrita • acesso permitido somente em alguns nodos

Listas lineares especiais mais usuais LIFO Last In First Out o último componente inserido

Listas lineares especiais mais usuais LIFO Last In First Out o último componente inserido é o primeiro a ser retirado FIFO First In First Out o primeiro componente inserido é também o primeiro a ser retirado Pilhas e filas Pilha Fila

Pilhas e Filas Exclusões Inserções Consultas Topo PILHA Base FILA Exclusões e Consultas Início

Pilhas e Filas Exclusões Inserções Consultas Topo PILHA Base FILA Exclusões e Consultas Início Final Inserções

Pilhas

Pilhas

Pilhas Operações sobre Pilhas Exclusões Inserções Consultas Topo • Criar uma pilha vazia •

Pilhas Operações sobre Pilhas Exclusões Inserções Consultas Topo • Criar uma pilha vazia • Inserir um elemento no topo da pilha • Remover um elemento do topo de pilha • Consultar o topo da pilha • Destruir a pilha • Verificar se é cheia • Verificar se é vazia Base

TAD Pilha Dados: numeros inteiros Operações: E_cheia entrada: o endereço da pilha processo: verifica

TAD Pilha Dados: numeros inteiros Operações: E_cheia entrada: o endereço da pilha processo: verifica se pilha esta na condição de cheia saida: 1 se cheia, 0 caso contrário (-1 se pilha não existe)

TAD Pilha E_vazia entrada: endereço da pilha processo: verifica se a pilha está na

TAD Pilha E_vazia entrada: endereço da pilha processo: verifica se a pilha está na condição de vazia saida: 1 se vazia, 0 caso contrario (-1 se a pilha não existe)

TAD Pilha Cria_pilha entrada: nenhuma processo: aloca a pilha e a coloca na condição

TAD Pilha Cria_pilha entrada: nenhuma processo: aloca a pilha e a coloca na condição de vazia saida: endereço da pilha

TAD Pilha Push entrada: endereço da variável que contém o endereço da pilha e

TAD Pilha Push entrada: endereço da variável que contém o endereço da pilha e o elemento processo: insere elemento no topo da pilha e atualiza pilha saida: 1 se sucesso , 0 se fracasso

TAD Pilha Pop entrada: endereço da variavel que contem o endereço da pilha e

TAD Pilha Pop entrada: endereço da variavel que contem o endereço da pilha e endereço do elemento que conterá o valor do elemento a ser removido processo: remove elemento do topo da pilha e atualiza pilha saida: 1 se sucesso e 0 se fracasso

TAD Pilha Top entrada: endereço da pilha e o endereço do elemento consultado processo:

TAD Pilha Top entrada: endereço da pilha e o endereço do elemento consultado processo: consulta o topo da pilha saida: 1 se sucesso e 0 se fracasso

TAD Pilha Libera_pilha entrada: endereço do endereço da pilha processo: libera toda área alocada

TAD Pilha Libera_pilha entrada: endereço do endereço da pilha processo: libera toda área alocada para a pilha saida: nenhuma

Pilhas implementadas por contiguidade física

Pilhas implementadas por contiguidade física

Pilha – contiguidade física Pilha - contiguidade física LIMITE • Implementada usando um arranjo

Pilha – contiguidade física Pilha - contiguidade física LIMITE • Implementada usando um arranjo Topo • Índices de controle da pilha: • BASE da pilha • TOPO atual da pilha • LIMITE máximo que pode ser ocupado pela pilha Base Pilha Índices do arranjo

Pilha – contiguidade física Exemplo de manipulação de uma pilha 1. Inicializar pilha de

Pilha – contiguidade física Exemplo de manipulação de uma pilha 1. Inicializar pilha de valores inteiros, a partir do índice 0, máximo 10 nós 2. Inserir nodo com valor 3 3. Inserir nodo com valor 7 4. Inserir nodo com valor 5 5. Remover nodo do topo 6. Consultar pilha Retorna “ 5” Retorna “ 7” MAX-1 9 8 7 6 6 5 5 4 4 3 3 2 TOPO PILHA BASE TOPO 3 PILHA 1 0 TOPO BASE 7 3 PILHA MAX-1 9 8 8 8 7 7 7 6 6 6 5 5 5 4 4 4 3 3 3 2 2 1 0 9 8 7 BASE MAX-1 TOPO 1 0 BASE 5 7 3 PILHA 1 0 TOPO BASE 7 3 PILHA 1 0

Pilha – contiguidade física Tipo de dados utilizado nos algoritmos para pilha implementada por

Pilha – contiguidade física Tipo de dados utilizado nos algoritmos para pilha implementada por contiguidade física: struct stack { int pilha[MAX]; int topo; }; typedef struct stack Pilha;

Pilha – contiguidade física Criação da pilha MAX - 1 9 8 7 6

Pilha – contiguidade física Criação da pilha MAX - 1 9 8 7 6 5 1. Alocar área para a pilha 2. Indicar que a pilha está vazia 4 3 2 Exemplo: Base 0 Topo – 1 MAX 10 1 Base Topo 0 Pilha

Algoritmo: criação de uma pilha Pilha *Cria_pilha(void) Pilha – contiguidade física Pilha *Cria_pilha(void) {

Algoritmo: criação de uma pilha Pilha *Cria_pilha(void) Pilha – contiguidade física Pilha *Cria_pilha(void) { Pilha *Ptp; Ptp = (Pilha*) malloc(sizeof(Pilha)); if (Ptp != NULL) Ptp->topo = -1; return Ptp; }

Verifica se pilha é cheia int E_cheia(Pilha *Ptp) { if ( Ptp == NULL)

Verifica se pilha é cheia int E_cheia(Pilha *Ptp) { if ( Ptp == NULL) return -1; if (Ptp->topo == MAX-1) return 1; else return 0; } int E_vazia(Pilha *Ptp) { if (Ptp == NULL) return -1; if (Ptp->topo == -1) return 1; else return 0; }

Pilha – contiguidade física Inserção de um elemento na pilha Operação PUSH 9 MAX

Pilha – contiguidade física Inserção de um elemento na pilha Operação PUSH 9 MAX -1 9 MAX - 1 8 7 6 5 4 3 2 1 0 8 7 6 5 4 3 Topo 2 1 Base 0 Pilha Base Pilha

Algoritmo: inserer elemento no topo da pilha Pilha – contiguidade física int Push(Pilha **Ptp,

Algoritmo: inserer elemento no topo da pilha Pilha – contiguidade física int Push(Pilha **Ptp, int elem) { if ((*Ptp) == NULL||(*Ptp)->topo == MAX-1) return 0; (*Ptp)->topo++; (*Ptp)->pilha[(*Ptp)->topo] = elem; return 1; }

Pilha – contiguidade física Remoção de um elemento da pilha Operação POP 9 MAX

Pilha – contiguidade física Remoção de um elemento da pilha Operação POP 9 MAX - 1 Topo 8 8 7 7 6 6 5 5 4 4 3 Base Topo 3 2 2 1 1 0 Pilha 9 MAX - 1 Base 0 Pilha

Algoritmo: Remover elemento do topo de Pilha int Pop(Pilha **Ptp, int *elem) { if

Algoritmo: Remover elemento do topo de Pilha int Pop(Pilha **Ptp, int *elem) { if ((*Ptp) == NULL || (*Ptp)->topo == -1) return 0; *elem = (*Ptp)->pilha[(*Ptp)->topo]; (*Ptp)->topo--; return 1; }

Pilha – contiguidade física Consulta o topa da pilha 9 MAX - 1 •

Pilha – contiguidade física Consulta o topa da pilha 9 MAX - 1 • Acesso somente ao elemento do topo da pilha Topo ? Base Pilha 8 7 6 5 4 3 2 1 0

Algoritmo: Consultar o elemento do topo de Pilha int Top(Pilha *Ptp, int *elem) {

Algoritmo: Consultar o elemento do topo de Pilha int Top(Pilha *Ptp, int *elem) { if (Ptp == NULL || Ptp->topo == -1) return 0; *elem = Ptp->pilha[Ptp->topo]; return 1; }

Destruição da pilha void Libera_pilha(Pilha** Ptp) void Libera_pilha(Pilha **Ptp) { free(*Ptp); *Ptp=NULL; }

Destruição da pilha void Libera_pilha(Pilha** Ptp) void Libera_pilha(Pilha **Ptp) { free(*Ptp); *Ptp=NULL; }

paeas. h typedef struct stack Pilha; int E_cheia(Pilha *Ptp); int E_vazia(Pilha *Ptp); Pilha *Cria_pilha(void);

paeas. h typedef struct stack Pilha; int E_cheia(Pilha *Ptp); int E_vazia(Pilha *Ptp); Pilha *Cria_pilha(void); int Push(Pilha **Ptp, int elem); int Pop(Pilha **Ptp, int *elem); Int Top(Pilha *Ptp, int *elem); void Libera_pilha(Pilha **Ptp);

Exercício para entregar agora Implemente o TAD utilizando uma estrutura de dados com alocação

Exercício para entregar agora Implemente o TAD utilizando uma estrutura de dados com alocação estática e acesso sequencial Implemente uma função que, usando o TAD Pilha, verifique se uma dada palavra representada como uma STRING (que não contenha brancos) é uma palíndromo (palavras que não se alteram quando lidas da direita para a esquerda ou da esquerda para a direita). Re. Exemplos: ANA, ADGHGDA. Retorne 1 se palavra é palindromo, e 0 caso contrario. Faça um programa que leia uma string (conjunto de palavras separadas por brancos) e indique quais palavras da string são palindromos e quais não são. A string eh dada por linha de comando

Pilhas implementadas por encadeamento

Pilhas implementadas por encadeamento

Pilha implementada por encadeamento Endereço do topo da pilha Pt. Pilha remoções Info ?

Pilha implementada por encadeamento Endereço do topo da pilha Pt. Pilha remoções Info ? consultas prox Topo da pilha inserções Topo Base da pilha Tipo de dados utilizado nos algoritmos: struct no{ int info; struct no* prox; }; typedef struct no Pilha;

Pilha por encadeamento Criação de pilha encadeada • Pilha criada vazia • Atribuir endereço

Pilha por encadeamento Criação de pilha encadeada • Pilha criada vazia • Atribuir endereço nulo para apontador que contém o endereço do topo da pilha

Algoritmo: Criar Pilha Encadeada Pilha* Cria_pilha(void) { return NULL; } Pilha por encadeamento

Algoritmo: Criar Pilha Encadeada Pilha* Cria_pilha(void) { return NULL; } Pilha por encadeamento

Pilha por encadeamento Inserção de um nodo em pilha encadeada • Novo nodo inserido

Pilha por encadeamento Inserção de um nodo em pilha encadeada • Novo nodo inserido sempre no topo da pilha Pt. Pilha Topo Novo nodo Topo Base

Algoritmo: Pilha por encadeamento Inserir nodo em Pilha Encadeada int Push(Pilha **Ptp, int elem)

Algoritmo: Pilha por encadeamento Inserir nodo em Pilha Encadeada int Push(Pilha **Ptp, int elem) { Pilha *pt; pt= (Pilha*)malloc(sizeof(Pilha)); if (pt == NULL) return 0; pt->prox = (*Ptp); pt->info = elem; (*Ptp) = pt; return 1; }

Pilha por encadeamento Desempilha um nodo de uma pilha encadeada • Só pode ser

Pilha por encadeamento Desempilha um nodo de uma pilha encadeada • Só pode ser removido o nodo do topo da pilha Nodo a ser removido Pt. Pilha Topo Base

Algoritmo: Desempilha nodo de Pilha Encadeada int Pop(Pilha * *Ptp, int* elem) int Pop(Pilha

Algoritmo: Desempilha nodo de Pilha Encadeada int Pop(Pilha * *Ptp, int* elem) int Pop(Pilha **Ptp, int *elem) { Pilha *aux = *Ptp; if (*Ptp == NULL) return 0; *elem = (*Ptp)->info; *Ptp= (*Ptp)->prox; free(aux); return 1; } Pilha por encadeamento

Pilha por encadeamento Consulta à pilha encadeada • Só pode ser acessado o nodo

Pilha por encadeamento Consulta à pilha encadeada • Só pode ser acessado o nodo do topo da pilha Nodo que pode ser acessado Pt. Pilha Topo Base

Algoritmo: Pilha por encadeamento Consultar nodo do topo de Pilha Encadeada int Top (Pilha

Algoritmo: Pilha por encadeamento Consultar nodo do topo de Pilha Encadeada int Top (Pilha *Ptp, int *elem) int Top(Pilha *Ptp, int *elem) { if (Ptp == NULL) return 0; *elem = Ptp->info; return 1; }

Pilha por encadeamento Destruição de uma pilha encadeada • Liberar espaço ocupado pelos nodos,

Pilha por encadeamento Destruição de uma pilha encadeada • Liberar espaço ocupado pelos nodos, sempre a partir do topo da pilha • No final: apontador para o topo = endereço nulo Pt. Pilha Topo Base Pt. Pilha = nil

Algoritmo: Destruir Pilha Encadeada void Libera_pilha(Pilha **Ptp) { Pilha *aux; while ((*Ptp) != NULL)

Algoritmo: Destruir Pilha Encadeada void Libera_pilha(Pilha **Ptp) { Pilha *aux; while ((*Ptp) != NULL) { aux = (*Ptp); (*Ptp) = (*Ptp)->prox; free(aux); } } Pilha por encadeamento

Verifica de pilha esta cheia int E_cheia(Pilha *Ptp) { return 0; } Verifica de

Verifica de pilha esta cheia int E_cheia(Pilha *Ptp) { return 0; } Verifica de pilha esta vazia int E_vazia(Pilha *Ptp) { if (Ptp == NULL) return 1; else return 0; }

Exercício Implemente o TAD Pilha utilizando alocação dinâmica de memória e acesso encadeado. Teste

Exercício Implemente o TAD Pilha utilizando alocação dinâmica de memória e acesso encadeado. Teste o programa para reconhecer quais palavras são palíndromos em uma dada frase.

Aplicação da estrutura de dados Pilha em avaliação de expressões aritméticas Forma das expressões

Aplicação da estrutura de dados Pilha em avaliação de expressões aritméticas Forma das expressões Considere: Operandos: [0, . . . , 9] Operadores: [+, -, /, x, ^] Delimitadores: [(, )] Exemplos: As operações são efetuadas de acordo com 2 + 3 * 5 = 17 a ordem de precedência dos operadores; (2 + 3) * 5 = 25 Os parênteses alteram a ordem natural de avaliação dos operadores.

Proponham um algoritmo para avaliar expressões aritméticas 22 – 56 / 2; (22 -56)/2;

Proponham um algoritmo para avaliar expressões aritméticas 22 – 56 / 2; (22 -56)/2; 40/(2 x(3 -1) +6); 2^3 x 4; 2^(3 x 4); ?

Notação Polonesa e Notação Polonesa Inversa Notação Polonesa (pré-fixada)- Proposta pelo matemático Jan lukasiewiscz

Notação Polonesa e Notação Polonesa Inversa Notação Polonesa (pré-fixada)- Proposta pelo matemático Jan lukasiewiscz em 1920 permite escrever uma expressão aritmética em que a precedência é implícita Notação Polonesa Inversa (pós-fixada) proposta por Charles Hamblin em 1950.

Notação Polonesa e Notação Polonesa Inversa expressão: ----2+5 x 3 2+3– 4 2 +

Notação Polonesa e Notação Polonesa Inversa expressão: ----2+5 x 3 2+3– 4 2 + (3 – 4) (2 + 4)/(3 -1) (2+4)/(3 -1)x 4 2^2*3 -4+1/2/(1+1) forma pósfixada 253 x+ 23+4234 -+ 24+31 -/ forma préfixada +2 x 53 -+234 +2– 34 / + 2 4 -3 1 24+31–/4 x x / +2 4 -3 1 4 22^3*4– 12/11+/+ + -*^2 2 3 4 / / 1 2 + 1 1

Forma pós-fixada para avaliar expressoes aritmeticas usando pilha float avalia_expressao(char *pos-fixada) Inicio Ptp aponta

Forma pós-fixada para avaliar expressoes aritmeticas usando pilha float avalia_expressao(char *pos-fixada) Inicio Ptp aponta para uma pilha vazia Enquanto (nao processou toda expressao pos-fixada) Inicio simbolo = token; se (simbolo é um operando) empilha simbolo na pilha Ptp senao inicio operando 2 = desempilha elemento da pilha Ptp operando 1 = desempilha elemento da pilha Ptp valor = operando 1 simbolo operando 2 empilha valor na pilha Ptp fim se Fim enquanto Retorna (desempilha o elemento da pilha Ptp) Fim da funçao

Como transformar uma expressão na forma infixa para pos-fixa? ? ? - Expressões entre

Como transformar uma expressão na forma infixa para pos-fixa? ? ? - Expressões entre parênteses devem ser convertidos de tal forma que possam ser tratadas como um único operando. - Somente operadores são empilhados. Um operador é empilhado apenas se possui precedência maior que o operador no topo da pilha. - Abre parênteses é sempre empilhado - Fecha parênteses nunca é empilhado (menor precedência). Todos os operadores são desempilhados até encontrar um ‘(‘. - Operandos e operadores desempilhados são colocados na expressão na forma pós-fixa

Algoritmo: char* pos-fixa(char* in-fixa) Inicio inicializa pilha de operadores e aloca area do tamanho

Algoritmo: char* pos-fixa(char* in-fixa) Inicio inicializa pilha de operadores e aloca area do tamanho da expressao in-fixa enquanto (não processou toda a expressao in-fixa) inicio simbolo = token se (simbolo é operando) coloca simbolo na expressao pos-fixa senao inicio enquanto (pilha não eh vazia E precedencia(topo da pilha, simbolo) inicio símbolo topo de pilha elem-topo = desempilha coloca elem-topo na expressao pos-fixa Precedencia(‘(‘, op) --- false fim enquanto Precedencia (op, ’(‘) ---- false, exceto op=‘)’ se (pilha eh vazia OU simbolo # ‘)’ ) Precedencia (op, ’)’) -----false, exceto op=‘(‘ empilha simbolo Precedencia (‘)’, op) --- indefinido senao enquanto ( (elem-topo = desempilha) != ‘(‘ ) coloca elem-topo na expressao pos-fixa; fim se Se precedência do topo da pilha maior que fim se símbolo true fim enquanto ( pilha não eh vazia)

Exercício usando pilha Escreva uma função que transforma uma expressão da forma in-fixa para

Exercício usando pilha Escreva uma função que transforma uma expressão da forma in-fixa para a forma pósfixa. Escreva uma função que avalie uma expressão na forma pós-fixa Escreva um programa que entra com a expressão aritmética pela linha de comando e avalia a expressão.

Exercício usando pilha – cont. Os operandos são números reais (positivos e negativos); Os

Exercício usando pilha – cont. Os operandos são números reais (positivos e negativos); Os operadores são: {+, -, x, /, ^} Os delimitadores são: {(, )} Ex: 3. 4 x 5 + ( 2. 1 – 12 ) (-23 + 24. 3 / 2. 1) ^ 3

Exercicio 1 - Altere a estrutura do TAD Pilha para conter caracter ( o

Exercicio 1 - Altere a estrutura do TAD Pilha para conter caracter ( o campo info deve conter dado do tipo char) 2 - Escreva as funçoes para o novo TAD 3 - Escreva um programa de aplicação, que dada uma string passada por linha de comando, verifique se os parenteses e conchetes estao corretamente balanceado. Use a Pilha para resolver o problema. Ex: (([[]])) correto (([)]) errado (a + b –(d)) correto