Sie sind auf Seite 1von 14

13/05/2013

Pilhas
Prof. Me. Ricardo Becker

Uma das estruturas de dados mais simples a pilha. Possivelmente por essa razo, a estrutura de dados mais utilizada em programao, sendo inclusive implementada diretamente pelo hardware A idia fundamental da pilha que todo o acesso a seus elementos feito atravs do seu topo. Assim, quando um elemento novo introduzido na pilha, passa a ser o elemento do topo, e o nico elemento que pode ser removido da pilha o do topo. Isto faz com que os elementos da pilha sejam retirados na ordem inversa ordem em que foram introduzidos:
o primeiro que sai o ltimo que entrou (a sigla LIFO last in, first out usada para descrever esta estratgia).
2

13/05/2013

Para entendermos o funcionamento de uma estrutura de pilha, podemos fazer uma analogia com uma pilha de pratos.
Se quisermos adicionar um prato na pilha, o colocamos no topo. Para pegar um prato da pilha, retiramos o do topo. Assim, temos que retirar o prato do topo para ter acesso ao prximo prato.

Cada novo elemento inserido no topo e s temos acesso ao elemento do topo da pilha.

Existem duas operaes bsicas que devem ser implementadas numa estrutura de pilha:
a operao para empilhar um novo elemento, inserindo-o no topo, e a operao para desempilhar um elemento, removendo-o do topo.

comum nos referirmos a essas duas operaes pelos termos em ingls push (empilhar) e pop (desempilhar).

A Figura ilustra o funcionamento conceitual de uma pilha.

13/05/2013

consideraremos duas implementaes de pilha:


usando vetor e usando lista encadeada.

Independente da estratgia de implementao, podemos definir a interface do tipo abstrato que representa uma estrutura de pilha. A interface composta pelas operaes que estaro disponibilizadas para manipular e acessar as informaes da pilha.

Neste exemplo, vamos considerar a implementao de cinco operaes:


criar uma estrutura de pilha; inserir um elemento no topo (push); remover o elemento do topo (pop); verificar se a pilha est vazia; liberar a estrutura de pilha.

13/05/2013

O arquivo pilha.h, que representa a interface do tipo, pode conter o seguinte cdigo:
typedef struct pilha Pilha; Pilha* cria (void); void push (Pilha (Pilha* Pilha* p, float v); float pop (Pilha* p); int vazia (Pilha* p); void libera (Pilha* p);

A funo cria aloca dinamicamente a estrutura da pilha, inicializa seus campos e retorna seu ponteiro; as funes push e pop inserem e retiram, respectivamente, um valor real na pilha; a funo vazia informa se a pilha est ou no vazia; a funo libera destri a pilha, liberando toda a memria usada pela estrutura.
typedef struct pilha Pilha; Pilha* cria (void); void push (Pilha (Pilha* Pilha* p, float v); float pop (Pilha* p); int vazia (Pilha* p); void libera (Pilha* p);
8

13/05/2013

Em aplicaes computacionais que precisam de uma estrutura de pilha, comum sabermos de antemo o nmero mximo de elementos que podem estar armazenados simultaneamente na pilha,
isto , a estrutura da pilha tem um limite conhecido.

Nestes casos, a implementao da pilha pode ser feita usando um vetor.

A implementao com vetor mais simples. Devemos ter um vetor (vet) para armazenar os elementos da pilha. Os elementos inseridos ocupam as primeiras posies do vetor. Desta forma, se temos n elementos armazenados na pilha, o elemento vet[n-1] representa o elemento do topo.

10

13/05/2013

A estrutura que representa o tipo pilha deve, portanto, ser composta pelo vetor e pelo nmero de elementos armazenados.
#define MAX 50 struct pilha { int n; float vet[MAX]; };

11

A funo para criar a pilha aloca dinamicamente essa estrutura e inicializa a pilha como sendo vazia, isto , com o nmero de elementos igual a zero.
Pilha* cria (void) { Pilha* p = (Pilha*) malloc(sizeof(Pilha)); p->n = 0; /* inicializa com zero elementos */ return p; }

12

13/05/2013

Para inserir um elemento na pilha, usamos a prxima posio livre do vetor. Devemos ainda assegurar que exista espao para a insero do novo elemento, tendo em vista que trata-se de um vetor com dimenso fixa.
void push (Pilha* p, float v) { if (p->n == MAX) { /* capacidade esgotada */ printf("Capacidade da pilha estourou.\n"); exit(1); /* aborta programa */ } /* insere elemento na prxima posio livre */ p->vet[p->n] = v; p->n++; }

13

A funo pop retira o elemento do topo da pilha, fornecendo seu valor como retorno. Pode-se tambm verificar se a pilha est ou no vazia.
float pop (Pilha* p) { float v; if (vazia(p)) { printf("Pilha vazia.\n"); exit(1); /* aborta programa */ } /* retira elemento do topo */ v = p->vet[p->n-1]; p->n--; return v; }
14

13/05/2013

A funo que verifica se a pilha est vazia pode ser dada por:
int vazia (Pilha* p) { return (p->n == 0); }

15

Finalmente, a funo para liberar a memria alocada pela pilha pode ser:
void libera (Pilha* p) { free(p); }

16

13/05/2013

Quando o nmero mximo de elementos que sero armazenados na pilha no conhecido, devemos implementar a pilha usando uma estrutura de dados dinmica, no caso, empregando uma lista encadeada. Os elementos so armazenados na lista e a pilha pode ser representada simplesmente por um ponteiro para o primeiro n da lista.

17

O n da lista para armazenar valores reais pode ser dado por:


struct no { float info; struct no* prox; }; typedef struct no No;

18

13/05/2013

A estrutura da pilha ento simplesmente:


struct pilha { No* prim; };

19

A funo cria aloca a estrutura da pilha e inicializa a lista como sendo vazia.
Pilha* cria (void) { Pilha* p = (Pilha*) malloc(sizeof(Pilha)); p->prim = NULL; return p; }

20

10

13/05/2013

O primeiro elemento da lista representa o topo da pilha. Cada novo elemento inserido no incio da lista e, conseqentemente, sempre que solicitado, retiramos o elemento tambm do incio da lista. Desta forma, precisamos de duas funes auxiliares da lista:
para inserir no incio e para remover do incio. Ambas as funes retornam o novo primeiro n da lista.

21

/* funo auxiliar: insere no incio */ No* ins_ini (No* l, float v) { No* p = (No*) malloc(sizeof(No)); p->info = v; p->prox = l; return p; } /* funo auxiliar: retira do incio */ No* ret_ini (No* l) { No* p = l->prox; free(l); return p; }
22

11

13/05/2013

As funes que manipulam a pilha fazem uso dessas funes de lista:


void push (Pilha* p, float v) { p->prim = ins_ini(p->prim,v); } float pop (Pilha* p) { float v; if (vazia(p)) { printf("Pilha vazia.\n"); exit(1); /* aborta programa */ } v = p->prim->info; p->prim = ret_ini(p->prim); return v; }

23

Pilha estar vazia se a lista estiver vazia:


int vazia (Pilha* p) { return (p->prim==NULL); }

24

12

13/05/2013

Por fim, a funo que libera a pilha deve antes liberar todos os elementos da lista.
void libera (Pilha* p) { No* q = p->prim; while (q!=NULL) { No* t = q->prox; free(q); q = t; } free(p); }

25

A rigor, pela definio da estrutura de pilha, s temos acesso ao elemento do topo. No entanto, para testar o cdigo, pode ser til implementarmos uma funo que imprima os valores armazenados na pilha. Os cdigos abaixo ilustram a implementao dessa funo nas duas verses de pilha (vetor e lista). A ordem de impresso adotada do topo para a base.
26

13

13/05/2013

/* imprime: verso com vetor */ void imprime (Pilha* p) { int i; for (i=p->n-1; i>=0; i--) printf("%f\n",p->vet[i]); }

/* imprime: verso com lista */ void imprime (Pilha* p) { No* q; for (q=p->prim; q!=NULL; q=q->prox) printf("%f\n",q->info); }
27

14

Das könnte Ihnen auch gefallen