Você está na página 1de 9

Estruturas de Dados

Pilhas e Filas

Estruturas lineares com disciplina de acesso


Diversas aplicaes envolvendo listas lineares requerem implementaes que impem limites para as operaes de incluso e remoo de elementos. Basicamente trata-se de situaes em que a posio do novo elemento pr-determinada, bem como o critrio para determinar quem deve ser removido da lista. Tais estruturas so muitas vezes denominadas de estruturas lineares com disciplina de acesso, e existem dois tipos principais: First In First Out (FIFO), os novos elementos so acrescentados no final da lista, e a excluso ocorre na extremidade oposta. Assim, ao remover um elemento, selecionamos aquele que est a mais tempo na lista, o que foi includo a mais tempo. Precisamos monitorar as duas extremidades da lista, pois na ponta inicial fazemos a excluso e na final fazemos a incluso. A analogia bsica deste tipo de estrutura uma fila de pessoas em que no h qualquer tipo de prioridade de atendimento, apenas a ordem de entrada das pessoas na fila. As extremidades costumam ser denominadas de incio e final.
Incio da fila Final da fila

Sada Fig. 1: Uma fila com 5 pessoas.

Entrada

Last In First Out (LIFO), os novos elementos so acrescentados na mesma extremidade de onde so removidos. Com isso, o elemento mais antigo na lista o ltimo a ser removido e o elemento mais recente na lista o primeiro a ser removido. Dessa forma, para implementar uma estrutura LIFO precisamos monitorar apenas uma de suas extremidades. A analogia fundamental deste tipo de estrutura a pilha de objetos, tais como pratos ou livros, e a extremidade sobre a qual devemos manter controle costuma ser chamada de topo.
Entrada Sada

Topo da pilha

Fig. 2: Uma pilha com 5 pratos.

Como qualquer lista linear, as estruturas LIFO (pilhas) e FIFO (filas) podem ser implementadas por encadeamento ou por contigidade. Neste material ser dada ateno apenas implementao por encadeamento. A discusso da implementao desses dois tipos de estrutura ser realizada por meio de uma lista encadeada simples de nmeros inteiros, cujo tipo de dado dos elementos dado na figura 3. Nos exemplos dados, optou-se por manter como descritor da lista tambm a quantidade de elementos da lista e, por simplicidade, no sero utilizadas subrotinas, para permitir melhor entendimento das operaes bsicas. Posteriormente, uma implementao equivalente utilizando subrotinas ser apresentada.

Prof. Antonio Cesar de Barros Munari

Estruturas de Dados

Pilhas e Filas
struct regLista { int valor; struct regLista *prox; }; typedef struct regLista TLista; Fig. 3: Definio do tipo de dados dos elementos da lista.

Pilhas
Como vimos anteriormente, o aspecto essencial da implementao de uma pilha (no ingls: stack) diz respeito forma como so construdas as suas rotinas de incluso (ou empilhamento, no ingls: push) e excluso (ou desempilhamento, no ingls: pop) de elementos. Como precisamos monitorar apenas uma das extremidades da lista, o topo, a varivel descritora da lista possui uma estrutura bastante simples, como mostra a figura 4. A inicializao do descritor consiste apenas em colocar um nulo em seu membro topo e um zero em seu membro qtde, como mostra a figura 5.
struct descrPilha { TLista *topo; int qtde; }; typedef struct descrPilha DPilha; () DPilha descritor; Fig. 4: Definio do tipo e da varivel descritora da pilha.

descritor.topo = NULL; descritor.qtde = 0;

Fig. 5: Inicializao do descritor da pilha.

A rotina de incluso consiste em alocar a memria para o novo elemento, preench-lo com o contedo til correspondente e fazer com que seu elemento seguinte seja aquele que era o topo da pilha at aquele momento. Finalmente, o endereo de memria do novo elemento deve ser colocado como sendo o novo valor do topo no descritor e o contador de elementos precisa ser incrementado para refletir a nova quantidade de elementos da pilha. Tudo isso realizado pelo cdigo apresentado na figura 6.
(...) aux = (TLista *) malloc(sizeof( TLista )); aux->valor = numero; aux->prox = descritor.topo; descritor.topo = aux; descritor.qtde++; (...) Fig. 6: Incluso de um elemento na pilha.

A figura 7 apresenta a situao inicial de uma pilha com 3 elementos e a posterior incluso de um novo n por meio do cdigo apresentado anteriormente.

Prof. Antonio Cesar de Barros Munari

Estruturas de Dados

Pilhas e Filas descritor


topo qtde 3

Estado da pilha ANTES da incluso


valor 10 prox valor 2 prox valor 3 prox /

descritor
topo qtde 4

Estado da pilha DEPOIS da incluso


valor 5 prox valor 10 prox valor 2 prox valor 3 prox /

Fig. 7: Representao da pilha antes e depois da incluso de um elemento.

A rotina de excluso vai, caso a pilha no esteja vazia, obter o endereo do elemento a ser excludo e copi-lo para uma varivel auxiliar. Em seguida, vai atualizar o descritor do topo e da quantidade e, por fim, eliminar a varivel correspondente ao elemento indicado. O cdigo da figura 8 realiza essa sequncia de tarefas.
(...) if( descritor.topo != NULL ) { aux = descritor.topo; descritor.topo = descritor.topo->prox; descritor.qtde--; free(aux); } (...) Fig. 8: Excluso de um elemento da pilha.

A figura 9 mostra a remoo de um elemento de uma pilha que contm originalmente 4 elementos. A simplicidade da implementao da pilha independe de a lista linear ser ou no duplamente encadeada. Utilizamos pilhas em diversas situaes prticas, como para gerenciar a execuo das rotinas em um computador (isso feito por meio da pilha de execuo do sistema), implementar recursos de desfazer (undo) em aplicaes como editores, bancos de dados e jogos, e no gerenciamento dos links visitados em um browser de navegao na internet, em que podemos
Prof. Antonio Cesar de Barros Munari 3

Estruturas de Dados

Pilhas e Filas sempre retornar de uma pgina diretamente para a visitada anteriormente. Tambm muito til para o processamento de strings, seja reconhecendo palndromos, invertendo palavras, verificando balanceamento de delimitadores e modificando a notao de expresses aritmticas. descritor
topo qtde 4

Estado da pilha ANTES da excluso


valor 5 prox

valor 10

prox valor 2 prox valor 3 prox /

descritor
topo qtde 3

Estado da pilha DEPOIS da excluso


valor 10 prox valor 2 prox valor 3 prox /

Fig. 9: Representao da pilha antes e depois da excluso de um elemento.

O programa apresentado a seguir implementa uma pilha bsica de nmeros inteiros em linguagem C. Para test-lo, adapte-o para imprimir o contedo da pilha antes e aps a excluso.
#include <stdio.h> struct regLista { int valor; struct regLista *prox; }; typedef struct regLista TLista; struct descrPilha { TLista *topo; int qtde; }; typedef struct descrPilha DPilha; int main() { int numero; DPilha descritor; TLista *aux; descritor.topo = NULL; descritor.qtde = 0; Prof. Antonio Cesar de Barros Munari 4

Estruturas de Dados

Pilhas e Filas
while(1) { printf("Informe o numero:\n"); scanf("%d", &numero); if( numero < 0 ) break; aux = (TLista *) malloc(sizeof( TLista )); aux->valor = numero; aux->prox = descritor.topo; descritor.topo = aux; descritor.qtde++; } printf("\n\nDigite 1 para excluir ou outra coisa para encerrar:\n"); scanf("%d", &numero); if(numero == 1) { if( descritor.topo != NULL ) { aux = descritor.topo; descritor.topo = descritor.topo->prox; descritor.qtde--; printf("\n\nExcluindo o valor %d da pilha\n", aux->valor); free(aux); } else printf("\n\nA lista estah vazia\n"); } return 0; }

Prof. Antonio Cesar de Barros Munari

Estruturas de Dados

Pilhas e Filas

Filas
As filas (no ingls: queue) caracterizam-se por possurem rotinas de incluso (ou enfileiramento, no ingls: enqueue) e excluso (ou desenfileiramento, no ingls: dequeue) de elementos operando em extremidades distintas da estrutura. Por esse motivo, o descritor da lista precisa carregar pelo menos dois ponteiros, uma para o seu incio e outro para o seu final, como mostra a figura 10. A inicializao do descritor consiste apenas em colocar um nulo em seus ponteiros e um zero em seu membro qtde, como mostra a figura 11.
struct descrFila { TLista *inicio; TLista *final; int qtde; }; typedef struct descrFila DFila; () DFila descritor; Fig. 10: Definio do tipo e da varivel descritora da fila.

descritor.inicio = NULL; descritor.final = NULL; descritor.qtde = 0;

Fig. 11: Inicializao do descritor da fila.

A rotina de incluso em um fila aloca a nova varivel dinamicamente e a configura com os dados teis correspondentes. Como o novo elemento o ltimo da fila, seu ponteiro para o prximo recebe um nulo, indicando que no existe nada alm dele naquele momento. O endereo de memria do novo elemento colocado no ponteiro descritor para o final da lista e no ponteiro de prximo do at ento ltimo elemento. Finalmente, o descritor de quantidade incrementado. Essa sequncia de operaes est indicada no cdigo da figura 12.
(...) aux = (TLista *) malloc(sizeof( TLista )); aux->valor = numero; aux->prox = NULL; if( descritor.inicio == NULL ) descritor.inicio = aux; else descritor.final->prox = aux; descritor.final = aux; descritor.qtde++; (...) Fig. 12: Incluso de um elemento na fila.

A figura 13 apresenta a situao inicial de uma fila com 3 elementos e a posterior incluso de um novo n por meio do cdigo apresentado anteriormente.

Prof. Antonio Cesar de Barros Munari

Estruturas de Dados

Pilhas e Filas descritor


inicio final qtde 3

Estado da fila ANTES da incluso

valor 5

prox valor 10 prox valor 2 prox /

descritor
inicio final qtde 4

Estado da fila DEPOIS da incluso


prox

valor 5

valor 10

prox valor 2 prox valor 3 prox /

Fig. 13: Representao da fila antes e depois da incluso de um elemento.

A rotina de excluso semelhante da pilha, uma vez que o elemento removido o que antecede logicamente todos os outros. Compare o cdigo da figura 14 com o da excluso da pilha mostrado anteriormente.
(...) if( descritor.inicio != NULL ) { aux = descritor.inicio; descritor.inicio = descritor.inicio->prox; descritor.qtde--; if( descritor.qtde == 0 ) descritor.final = NULL; free(aux); } (...) Fig. 14: Excluso de um elemento da fila.

A figura 15 mostra a remoo de um elemento de uma fila que contm originalmente 4 elementos.

Prof. Antonio Cesar de Barros Munari

Estruturas de Dados

Pilhas e Filas descritor


inicio final qtde 4

Estado da fila ANTES da excluso


prox

valor 5

valor 10

prox valor 2 prox valor 3 prox /

descritor
inicio final qtde 3

Estado da fila DEPOIS da excluso

valor 10

prox valor 2 prox valor 3 prox /

Fig. 15: Representao da fila antes e depois da excluso de um elemento.

As filas so extensamente utilizadas em aplicaes de computao, como filas de impresso e outros jobs para processamento. Tambm so utilizadas para simular o comportamento de filas do mundo real e para orientar a sequncia de processamento em aplicaes dirigidas por eventos. O programa a seguir ilustra a implementao completa de uma fila de nmeros inteiros representada por encadeamento em linguagem C. Para test-lo, adapte-o para imprimir o contedo da fila antes e aps a excluso.
#include <stdio.h> struct regLista { int valor; struct regLista *prox; }; typedef struct regLista TLista; struct descrFila { TLista *inicio; TLista *final; int qtde; }; typedef struct descrFila DFila; int main() { int numero; DFila descritor; TLista *aux; descritor.inicio = NULL; Prof. Antonio Cesar de Barros Munari 8

Estruturas de Dados

Pilhas e Filas
descritor.final = NULL; descritor.qtde = 0; while(1) { printf("Informe o numero:\n"); scanf("%d", &numero); if( numero < 0 ) break; aux = (TLista *) malloc(sizeof( TLista )); aux->valor = numero; aux->prox = NULL; if( descritor.inicio == NULL ) descritor.inicio = aux; else descritor.final->prox = aux; descritor.final = aux; descritor.qtde++; } printf("\n\nDigite 1 para excluir ou outra coisa para encerrar:\n"); scanf("%d", &numero); if(numero == 1) { if( descritor.inicio != NULL ) { aux = descritor.inicio; descritor.inicio = descritor.inicio->prox; descritor.qtde--; if( descritor.qtde == 0 ) descritor.final = NULL; printf("\n\nExcluindo o valor %d da lista\n", aux->valor); free(aux); } else printf("\n\nA lista estah vazia\n"); } return 0; }

Prof. Antonio Cesar de Barros Munari

Você também pode gostar