Sie sind auf Seite 1von 9

Projeto de Algoritmos

Home | Prefcio | Livros | Stios WWW | ndice

Pilhas
Uma pilha uma das vrias estruturas de dados que admitem remoo de elementos e insero de novos elementos. Mais especificamente, uma pilha (= stack ) uma estrutura sujeita seguinte regra de operao: sempre que houver uma remoo, o elemento removido o que est na estrutura h menos tempo. Em outras palavras, o primeiro objeto a ser inserido na pilha o ltimo a ser removido. Essa poltica conhecida pela sigla LIFO (= Last-In-First-Out ). Veja o verbete Stack (data structure) na Wikipedia.

Implementao em um vetor
Suponha que nossa pilha est armazenada em um vetor p i l h a [ 0 . . n 1 ] . Suponha ainda que os elementos de p i l h aso nmeros inteiros. (Isto s um exemplo; os elementos de p i l h a poderiam ser objetos de qualquer outro tipo.) A parte do vetor ocupada pela pilha ser p i l h a [ 0 . . t 1 ].
0 t N 1

O ndice tindica o topo (= top) da pilha. Esta a primeira posio vaga da pilha. A pilha est vazia se tvale 0e cheia se tvale n . Para remover um elemento da pilha esta operao conhecida como desempilhar (= to pop) faa
x=p i l h a [ t ] ;

Isso equivale ao par de instrues "t=1 ;x=p i l h a [ t ] ; " nesta ordem. claro que voc s deve desempilhar se tiver certeza de que a pilha no est vazia. Para consultar a pilha sem desempilhar faa x = p i l h a [ t 1 ] . Para inserir ou seja, para empilhar (= to push) um objeto yna pilha faa
p i l h a [ t + + ]=y ;

Isso equivale ao par de instrues "p i l h a [ t ]=y ;t+ =1 ; " nesta ordem. Antes de empilhar, verifique se a pilha j est cheia para evitar que ela transborde (ou seja, para evitar um overflow). Em geral, a tentativa de inserir em uma pilha cheia uma situao excepcional,

que indica um mau planejamento lgico do seu programa.

Exerccios
1. Suponha que, diferentemente da conveno adotada no texto, a parte do vetor ocupada pela pilha p i l h a [ 0 . . t ] . Escreva a instruo que remove um elemento da pilha. Escreva a instruo que insere um objeto yna pilha. 2. Escreva funes e m p i l h ae d e s e m p i l h apara manipular uma pilha. Lembre-se de que uma pilha um pacote com dois objetos: um vetor e um ndice. No use variveis globais. Quais os parmetros de suas funes?

Aplicao: parnteses e colchetes


Suponha que queremos decidir se uma dada sequncia de parnteses e colchetes est bemformada (ou seja, parnteses e colchetes so fechados na ordem inversa quela em que forma abertos). Por exemplo, a primeira das sequncias abaixo est bem-formada enquanto a segunda no est.
(()[()]) ([)]

Suponha que a sequncia de parnteses e colchetes est armazenada em uma cadeia de caracteres (= string) s . Como hbito em C, o ltimo caractere da cadeia o caractere nulo, ' \ 0 ' .
/ /Af u n od e v o l v e1s eac a d e i asc o n t mu m as e q u n c i a / /b e m f o r m a d ad ep a r n t e s e sec o l c h e t e sed e v o l v e0s e / /as e q u n c i ae s t m a l f o r m a d a . i n tb e m F o r m a d a (c h a rs [ ] ) { c h a r* p i l h a ;i n tt ; i n tn ,i ; n=s t r l e n (s ) ; p i l h a=m a l l o c c (n*s i z e o f( c h a r ) ) ; t=0 ; f o r( i=0 ;s [ i ]! =' \ 0 ' ;+ + i ){ / /ap i l h ae s t a r m a z e n a d an ov e t o rp i l h a [ 0 . . t 1 ] s w i t c h( s [ i ] ){ c a s e' ) ' :i f( t! =0& &p i l h a [ t 1 ]= =' ( ' ) t ; e l s er e t u r n0 ; b r e a k ; c a s e' ] ' :i f( t! =0& &p i l h a [ t 1 ]= =' [ ' ) t ; e l s er e t u r n0 ;

b r e a k ; d e f a u l t : p i l h a [ t + + ]=s [ i ] ; } } r e t u r nt= =0 ; }

(Eu deveria ter invocado f r e e (p i l h a ) antes de cada r e t u r n . S no fiz isso para no obscurecer a lgica da funo.) Note que a pilha no transborda porque nunca ter mais elementos que o nmero de caracteres de s .

Exerccios
Eis algumas questes sobre a funo b e m F o r m a d a : 3. A funo funciona corretamente se stem apenas dois elementos? apenas um? nenhum? 4. Mostre que no incio de cada iterao sest bem-formada se e somente se a sequncia p i l h a [ 0 . . t 1 ]s [ i . . . ] estiver bem-formada. 5. Escreva uma verso melhorada da funo b e m F o r m a d aque desaloque o vetor p i l h aantes de terminar a execuo da funo. [Soluo]

Outra aplicao: notao polonesa


Na notao usual de expresses aritmticas, os operadores so escritos entre os operandos; por isso, a notao chamada infixa. Na notao polonesa, ou posfixa, os operadores so escritos depois dos operandos. (A propsito, veja exerccio sobre expresses aritmticas e rvores binrias.) Exemplo:

infixa
( A + B * C ) ( A * ( B + C ) / D E )

posfixa
A B C * + A B C + * D / E -

( A + B * ( C D * ( E F ) G * H ) I * 3 )A B C D E F * G H * * + I 3 * ( A + B * C / D * E F ) ( A + ( B ( C + ( D ( E + F ) ) ) ) ) A B C * D / E * + F A B C D E F + + +

( A * ( B + ( C * ( D + ( E * ( F + G ) ) ) ) ) )A B C D E F G + * + * + *

A notao posfixa dispensa parnteses. A ordem dos operandos a mesma nas expresses infixa e posfixa. Nosso problema:

Traduzir para notao posfixa a expresso infixa armazenada em uma cadeia de caracteres i n f . Para simplificar nossa vida, vamos supor que a expresso infixa est correta e consiste apenas de letras, abre-parntese, fecha-parntese e smbolos para as quatro operaes aritmticas. Vamos supor tambm que cada nome de varivel tem uma letra apenas. Finalmente, vamos supor que a expresso toda est embrulhada em um par de parnteses, isto , i n f [ 0 ]vale ' ( 'e os dois ltimos elementos de i n fso ' ) 'e ' \ 0 ' . Usaremos uma pilha para resolver o problema. Como a expresso infixa est embrulhada em um par de parnteses, no precisamos nos preocupar com pilha vazia!
/ /Af u n oa b a i x or e c e b eu m ae x p r e s s oi n f i x ai n fe / /d e v o l v eac o r r e s p o n d e n t ee x p r e s s op o s f i x a . c h a r* i n f i x a P a r a P o s f i x a (c h a ri n f [ ] ){ c h a r* p o s f ; c h a r* p i ;i n tt ;/ /p i l h a i n tn ,i ,j ; n=s t r l e n (i n f ) ; p o s f=m a l l o c c (n*s i z e o f( c h a r ) ) ; p i=m a l l o c c (n*s i z e o f( c h a r ) ) ; t=0 ; p i [ t + + ]=i n f [ 0 ] ; / /e m p i l h a' ( ' f o r( j=0 ,i=1 ;/ * X * /i n f [ i ]! =' \ 0 ' ;+ + i ){ / /ap i l h ae s t e mp i [ 0 . . t 1 ] s w i t c h( i n f [ i ] ){ c h a rx ; c a s e' ( ' :p i [ t + + ]=i n f [ i ] ; / /e m p i l h a b r e a k ; c a s e' ) ' :w h i l e( 1 ){ / /d e s e m p i l h a x=p i [ t ] ; i f( x= =' ( ' )b r e a k ; p o s f [ j + + ]=x ; } b r e a k ; c a s e' + ' : c a s e' ' :w h i l e( 1 ){ x=p i [ t 1 ] ; i f( x= =' ( ' )b r e a k ; t ; / /d e s e m p i l h a p o s f [ j + + ]=x ; } p i [ t + + ]=i n f [ i ] ; / /e m p i l h a b r e a k ; c a s e' * ' : c a s e' / ' :w h i l e( 1 ){ x=p i [ t 1 ] ; i f( x= =' ( '| |x= =' + '| |x= =' ' ) b r e a k ; t ; p o s f [ j + + ]=x ; } p i [ t + + ]=i n f [ i ] ; b r e a k ; d e f a u l t : p o s f [ j + + ]=i n f [ i ] ; }

} f r e e (p i ) ; p o s f [ j ]=' \ 0 ' ; r e t u r np o s f ; }

[Veja outra maneira de escrever a funo tirando proveito dos recursos sintticos da linguagem C.] Constantes e variveis vo diretamente de i n fpara p o s f . Abre-parntese vai para a pilha. Ao encontrar um fecha-parntese, a funo remove tudo da pilha at o abreparntese inclusive. Ao encontrar um +ou -a funo desempilha tudo at um abre-parntese exclusive. Ao encontrar um *ou /desempilha tudo at um abre-parntese ou um +ou um . Eis o resultado da aplicao da funo expresso infixa ( A * ( B * C + D ) ). A tabela abaixo registra os valores das variveis a cada passagem pelo ponto X :
i n f [ 0 . . i 1 ] ( ( A ( A * ( A * ( ( A * ( B ( A * ( B * ( A * ( B * C ( A * ( B * C + ( A * ( B * C + D ( A * ( B * C + D ) ( A * ( B * C + D ) ) p i [ 0 . . t 1 ] p o s f [ 0 . . j 1 ] ( ( A ( * A ( * ( A ( * ( A B ( * ( * A B ( * ( * A B C ( * ( + A B C * ( * ( + A B C * D ( * A B C * D + A B C * D + *

Exerccios
6. Aplique o algoritmo de converso para a notao posfixa expresso aritmtica
( A+B )*D+E/( F+A*D )+C

7. Considere a funo i n f i x a P a r a P o s f i x a . Suponha que a expresso infixa i n ftem ncaracteres (sem contar o ' \ 0 'final). Que tamanho a pilha p ipode atingir, no pior caso? Em outras palavras, qual o valor mximo da varivel tno pior caso? Que acontece se o nmero de abre-parnteses na expresso for limitado (menor que 6, por exemplo)? 8. No cdigo da funo i n f i x a P a r a P o s f i x a , alguns casos tm um w h i l e( 1 ) . Escreva uma nova verso sem esses w h i l e . (Dica: troque o f o rexterno por um w h i l eapropriado.) 9. Reescreva a funo i n f i x a P a r a P o s f i x asem supor que a expresso infixa est embrulhada em um par de parnteses. 10. Reescreva a funo i n f i x a P a r a P o s f i x asupondo que a expresso pode ter parnteses e colchetes.

11. Reescreva a funo i n f i x a P a r a P o s f i x asupondo que a expresso pode no estar bem-formada.

Exerccios
12. VALOR DE EXPRESSO POLONESA. Suponha que p o s f uma string que guarda uma expresso aritmtica em notao posfixa. Suponha que p o s fno vazio e contm somente os operadores + , , * e / (todos exigem dois operandos). Suponha tambm que a expresso no tem constantes e que todos os nomes de variveis na expresso consistem de uma nica letra maiscula (A ,...,Z ). Suponha ainda que temos um vetor t a b e l aque d os valores das variveis (todas as variveis tm valores inteiros):
t a b e l a [ 0 ] o

valor da varivel A , t a b e l a [ 1 ] o valor da varivel Betc. Escreva uma funo que calcule o valor da expresso p o s f . Cuidado com divises por zero! 13. Escreva um algoritmo que use uma pilha para inverter a ordem das letras de cada palavra de uma string, preservando a ordem das palavras. Por exemplo, dado o texto E S T EE X E R C I C I OEM U I T OF A C I L a sada deve ser E T S EO I C I C R E X EE O T I U ML I C A F . (Lembre-se: strings em C terminam com ' \ 0 ' .) 14. Digamos que nosso alfabeto formado pelas letras a , be c . Considere o seguinte conjunto de cadeias de caracteres sobre nosso alfabeto:
c , a c a , b c b , a b c b a , b a c a b , a a c a a , b b c b b ,

...

Qualquer cadeia deste conjunto tem a forma Wc M, onde W uma sequncia de letras que s contm ae be M o inverso de W, ou seja, M W lido de trs para frente. Escreva um programa que determina se uma cadeia X pertence ou no ao nosso conjunto, ou seja, determina se X da forma Wc M. 15. PERMUT AES PRODUZIDAS PELO DESEMPILHAR. Suponha que os inteiros 1,2,3,4 so colocados, nesta ordem, numa pilha inicialmente vazia. Depois de empilhar cada inteiro, voc pode retirar zero ou mais elementos da pilha. Cada elemento desempilhado impresso numa folha de papel. Por exemplo, a sequncia de operaes empilha 1, empilha 2, desempilha, empilha 3, desempilha, desempilha, empilha 4, desempilha, produz a impresso da sequncia 2,3,1,4. Quais das 24 permutaes de 1,2,3,4 podem ser obtidas desta maneira?

Pilha implementada em uma lista encadeada


Como implementar uma pilha em uma lista encadeada? Digamos que as clulas da lista so do

tipo c e l u l a :
t y p e d e fs t r u c tc e l{ i n t c o n t e u d o ; s t r u c tc e l* p r o x ; }c e l u l a ;

Decises de projeto: Vamos supor que nossa lista tem uma clula-cabea (ou seja, vamos supor que a primeira clula da lista no faz parte da pilha). Vamos supor que o topo da pilha est na segunda clula e no na ltima (por qu?). A pilha pode ser criada e inicializada assim:
c e l u l ac a b e c a ; c e l u l a* t p ; t p=& c a b e a ; t p > p r o x=N U L L ;

Para ter acesso pilha, s preciso do ponteiro t p . De acordo com nossa deciso de projeto, teremos sempre t p== & c a b e c a . A pilha est vazia se t p > p r o x== N U L L .
/ /I n s e r eu me l e m e n t oyn ap i l h at p . v o i de m p i l h a (i n ty ,c e l u l a* t p ){ c e l u l a* n o v a ; n o v a=m a l l o c c (s i z e o f( c e l u l a ) ) ; n o v a > c o n t e u d o=y ; n o v a > p r o x =t p > p r o x ; t p > p r o x=n o v a ; } / /R e m o v eu me l e m e n t od ap i l h at p . / /S u p eq u eap i l h an oe s t v a z i a . / /D e v o l v eoe l e m e n t or e m o v i d o . i n td e s e m p i l h a (c e l u l a* t p ){ i n tx ; c e l u l a* p ; p=t p > p r o x ; x=p > c o n t e u d o ; t p > p r o x=p > p r o x ; f r e e (p ) ; r e t u r nx ; }

Exerccios
16. Implemente um pilha em uma lista encadeada sem clula-cabea (s pra ver ver que dor de cabea isso d!). A pilha ser dada pelo endereo da primeira clula da lista (que tambm o topo da pilha). 17. Reescreva as funes b e m F o r m a d ae i n f i x a P a r a P o s f i x aarmazenando a pilha em uma lista encadeada. 18. Resolva o problem da intercalao de duas listas ordenadas.

19. Suponha dada uma lista encadeada que armazena nmeros inteiros. Cada clula da lista tema estrutura abaixo.
s t r u c tc e l{ i n t c o n t e u d o ; s t r u c tc e l* p r o x ; } ;

Escreva uma funo que transforme a lista em duas: a primeira contendo as clulas cujo contedo par e a segunda aquelas cujo contedo mpar.

Apndice: A pilha de execuo de um programa


Para executar um programa, o computador usa uma "pilha de execuo". A operao pode ser descrita conceitualmente da seguinte maneira. Todo programa C composto por uma ou mais funes (sendo m a i na primeira funo a ser executada). Ao encontrar a invocao de uma funo, o computador cria um novo "espao de trabalho", que contm todos os parmetros e todas as variveis locais da funo. Esse espao de trabalho colocado na pilha de execuo (sobre o espao de trabalho que invocou a funo) e a execuo da funo comea (confinada ao seu espao de trabalho). Quando a execuo da funo termina, o seu espao de trabalho retirado da pilha e descartado. O espao de trabalho que estiver agora no topo da pilha reativado e a execuo retomada do ponto em que havia sido interrompida. Considere o seguinte exemplo:
i n tG (i n ta ,i n tb ){ i n tx ; x=a+b ; r e t u r nx ; } i n tF (i n ti ,j ,k ){ i n tx ; x=/ * 2 * /G (i ,j )/ * 3 * / ; x=x+k ; r e t u r nx ; } i n tm a i n (v o i d ){ i n ti ,j ,k ,y ; i=1 1 1 ;j=2 2 2 ;k=4 4 4 ; y=/ * 1 * /F (i ,j ,k )/ * 4 * / ; p r i n t f (" % d \ n " ,y ) ; r e t u r nE X I T _ S U C C E S S ; }

A execuo do programa prossegue da seguinte maneira: Um espao de trabalho criado para a funo m a i ne colocado na pilha de execuo. O espao contm as variveis locais i ,j , ke y . A execuo de m a i ncomea.

No ponto 1 , a execuo de m a i n temporariamente interrompida e um espao de trabalho para a funo F colocado na pilha. Esse espao contm os parmetros i ,j , kda funo (com valores 1 1 1 ,2 2 2e 4 4 4respectivamente) e a varivel local x . Comea ento a execuo de F . No ponto 2 , a execuo de F interrompida e um espao de trabalho para a funo G colocado na pilha. Esse espao contm os parmetros ae bda funo (com valores 1 1 1e 2 2 2respectivamente) e a varivel local x . Em seguida, comea a execuo de G . Quando a execuo de Gtermina, a funo devolve 3 3 3 . O espao de trabalho de G removido da pilha e descartado. O espao de trabalho de F(que agora est no topo da pilha de execuo) reativado e a execuo retomada no ponto 3 . A primeira instruo executada "x=3 3 3 ; ". Quando a execuo de Ftermina, a funo devolve 7 7 7 . O espao de trabalho de F removido da pilha e descartado. O espao de trabalho de m a i n(que agora est no topo da pilha) reativado e a execuo retomada no ponto 4 . A primeira instruo executada "y=7 7 7 ; ". No nosso exemplo, Fe Gso funes distintas. Mas tudo funcionaria da mesma maneira se Fe Gfossem idnticas, ou seja, se Ffosse uma funo recursiva.

Exerccios
20. Considere a funo recursiva abaixo. Escreva uma verso iterativa da funo que simule o comportamento da verso recursiva. Use uma pilha.
i n tT T T (i n tx [ ] ,i n tn ){ i f( n= =0 )r e t u r n0 ; i f( x [ n ]>0 )r e t u r nx [ n ]+T T T (x ,n 1 ) ; e l s er e t u r nT T T (x ,n 1 ) ; }

URL of this site: www.ime.usp.br/~pf/algoritmos/ Last modified: Tue Apr 23 08:06:54 BRT 2013 Paulo Feofiloff IME-USP

Das könnte Ihnen auch gefallen