Вы находитесь на странице: 1из 10

Pilhas

ProjetodeAlgoritmos | LinguagemC | Iꀺndice Pilhas Umapilhaéumaestruturadedadosqueadmite remoção

Umapilhaéumaestruturadedadosqueadmiteremoçãodeelementoseinserçãodenovosobjetos. Mais especi icamente,uma pilha(=stack) éumaestruturasujeitaàseguinteregradeoperação: sempreque houverumaremoção,

oelementoremovidoéoqueestánaestruturahámenostempo.

Emoutraspalavras,oprimeiroobjetoaserinseridonapilhaéoúltimoaserremovido.Essapolıt́icaé

conhecidapelasiglaLIFO(=Last‑In‑First‑Out).

Implementaçãoemumvetor

Suponhaquenossapilhaestáarmazenadaemumvetor pilha[0

vetoréirrelevante:elespodemserinteiros,caracteres,ponteiros,etc.) Digamosqueapartedovetor ocupadapelapilhaé

N­1].

(Anaturezadoselementosdo

pilha[0

t­1].

Oıńdicetindicaaprimeiraposiçãovagadapilhaet­1éoıńdicedotopodapilha. Apilhaestávaziaset vale0echeiasetvaleN. Noexemploda igura,oscaracteresA,B,…,Hforaminseridosnapilhanessa ordem:

0

t

N­1

A

B

C

D

E

F

G

H

   

Pararemover,outirar,umelementodapilha—estaoperaçãoéconhecidacomodesempilhar(=topop)—

faça

x = pilha[­­t];

Issoequivaleaopardeinstruções "t­=1; x=pilha[t];",nessaordem. Eꀺclaroquevocêsódeve desempilharsetivercertezadequeapilhanãoestávazia.

Parainserir,oucolocar,umobjetoynapilha—aoperaçãoéconhecidacomoempilhar(=topush)—faça

pilha[t++] = y;

11/09/2016

Pilhas

Issoequivaleaopardeinstruções "pilha[t]=y; t+=1;",nessaordem. Antesdeempilhar,certi ique‑ sedequeapilhanãoestácheia,paraevitarumtransbordamento(=over螅ⴰlow).

Eꀺconvenienteembalaressasoperaçõesempequenasfunções.Seosobjetoscomqueestamoslidandosão

caracteres,porexemplo,podemosescrever

char desempilha (void) { return pilha[­­t];

}

void empilha (char y) { pilha[t++] = y;

}

Estamossupondoaquiqueasvariáveispilhaetsãoglobais,istoé,foramdeclaradasforadocódigodas funções. (Paracompletaropacote,precisarıámosdemaistrêsfunções:umaquecrieumapilha,umaque veri iqueseapilhaestávaziaeumaqueveri iqueseapilhaestácheia.Vejaexercıćioabaixo.)

Exercícios1

1.Suponhaque,diferentementedaconvençãoadotadanotexto,apartedovetorocupadapelapilhaé

pilha[1

t].Escrevaocódigodasfunçõesempilha,desempilha,pilhavaziaepilhacheia.

2.Escrevaumalgoritmoqueuseumapilhaparainverteraordemdasletrasdecadapalavradeumastring,

preservandoaordemdaspalavras.Porexemplo,paraastring ESTE EXERCICIO E MUITO FACIL o

resultadodeveser ETSE OICICREXE E OTIUM LICAF.

3.Mꀺ́ꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺ̃ꀺꀺꀺꀺꀺꀺꀺꀺ(ꀺꀺꀺꀺꀺ̃ꀺ1). Escrevaummódulopilhadechars.cqueimplemente umapilhadecaracteres.Omódulodeveconterasfunções criapilha, empilha, desempilha, pilhavazia, pilhacheia. Trateosparâmetrosdapilha(ovetorpilhaeoıńdicet)comovariáveisglobais domódulo. Escrevatambémumainterfacepilhadechars.hparaomódulo.[Solução.]

4.Pꀺꀺꀺꀺꀺꀺꀺꀺ̃ꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺ. Suponhaqueoscaracteres1,2,3,4sãocolocados,nestaordem, numapilhainicialmentevazia.Depoisdeempilharumcaractere,vocêpodetirarzerooumaiselementosda pilha.Cadaelementodesempilhadoéimpressonumafolhadepapel.Porexemplo,asequênciadeoperações

empilha1,empilha2,desempilha,empilha3,desempilha,desempilha,empilha4,desempilha,

produzaimpressãodasequência2,3,1,4.Quaisdas24permutaçõesde1,2,3,4podemserobtidasdessa

maneira?

5.[Sedgewick] Ofragmentodeprogramaabaixomanipulaumapilhadecaracteres. (Afunçãoespiapilha devolveumacópiadotopodapilha,masnãotiraesseelementodapilha.) Diga,emportuguês,oqueo fragmentofaz. Escrevaumfragmentodecódigoequivalentequesejabemmaiscurtoemaissimples.

if (pilhavazia ()) empilha ('B'); else {

if (espiapilha () != 'A')

else { while (!pilhavazia () && espiapilha () == 'A') desempilha (); empilha ('B'); } }

empilha ('B');

Aplicação:parêntesesecolchetes

Considereoproblemadedecidirseumadadasequênciadeparêntesesecolchetesestábem‑formada(ou seja,parêntesesecolchetessãofechadosnaordeminversaàquelaemqueforamabertos). Porexemplo,a sequência

11/09/2016

(

(

)

Pilhas

[

(

)

]

)

estábem‑formada,enquanto ( [ ) ] estámalformada. Suponhaqueasequênciadeparêntesese colchetesestáarmazenadaemumastring(cadeiadecaracteres) s. ComoéhábitoemC,oúltimo caracteredastringé'\0' (ocaracterenulo).

Usaremosumapilhapararesolveroproblema. Oalgoritmoésimples:examineastringdaesquerdapara adireitaeempilheosparêntesesecolchetesesquerdosàesperadequeapareçamoscorrespondentes parêntesesecolchetesdireitos.

Parasimpli icar,asvariáveispilhaetserãoglobais. SuporemostambémqueotamanhoNdovetorque abrigaapilhaémaiorqueotamanhodastringeportantoapilhajamaistransborda.

#define N 100 char pilha[N]; int t;

// Esta função devolve 1 se a string s contém uma // sequência bem­formada de parênteses e colchetes // e devolve 0 se a sequência é malformada.

int bemFormada (char s[]) { int i; criapilha ();

for (i = 0; s[i] != '\0'; ++i) { char c; switch (s[i]) { case ')': if (pilhavazia ()) return 0;

c = desempilha ();

if (c != '(') return 0; break; case ']': if (pilhavazia ()) return 0;

c = desempilha ();

if (c != '[') return 0;

break;

default: empilha (s[i]);

}

}

return pilhavazia ();

}

void criapilha (void) { t = 0;

}

void empilha (char y) { pilha[t++] = y;

}

char desempilha (void) { return pilha[­­t];

}

int pilhavazia (void) { return t <= 0;

}

11/09/2016

Exercícios2

Pilhas

1.Dêumade iniçãoformaldesequênciabem‑formadadeparêntesesecolchetes.Sugestão:dêumade inição recursiva.

2.AfunçãobemFormadafuncionacorretamenteseasequênciastemapenasdoiselementos?apenasum?

nenhum?

3.ConsidereafunçãobemFormada.Mostrequenoinıćiodecadaiteraçãosestábem‑formadaseesomentesea

sequência pilha[0

t­1]s[i

]

estiverbem‑formada.

4.EscrevaumaversãodafunçãobemFormadaquealoqueapilhadinamicamente.

5.Digamosquenossoalfabetocontémapenasasletrasa,bec.Considereoseguinteconjuntodestringssobre

nossoalfabeto: c, aca, bcb, abcba, bacab, aacaa, bbcbb,… Qualquerstringdesseconjuntotemaforma WcM,sendoWumasequênciadeletrasquesócontémaeb e MoinversodeW (ouseja,MWlidodetrás parafrente).EscrevaumprogramaquedecidaseumastringXpertenceounãoaonossoconjunto,ouseja, decidaseXédaformaWcM.

Outraaplicação:notaçãopolonesa

Nanotaçãousualdeexpressõesaritméticas,osoperadoressãoescritosentreosoperandos; porisso,a notaçãoéchamadain螅ⴰixa. Nanotaçãopos螅ⴰixa,oupolonesa,osoperadoressãoescritosdepoisdos operandos. Eisalgunsexemplosdeexpressõesin ixasecorrespondentesexpressõespos ixas:

in ixa

pos ixa

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

ABC*+ ABC+*D/E­

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

ABCDEF­*­GH*­*+I3*­

(A+B*C/D*E­F)

ABC*D/E*+F­

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

AB+CD*+EF*G*­

(A+(B­(C+(D­(E+F)))))

ABCDEF+­+­+

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

ABCDEFG+*+*+*

Notequeosoperandos(A,B,C,etc.)aparecemnamesmaordemnaexpressãoin ixaenacorrespondente expressãopos ixa. Notetambémqueanotaçãopos ixadispensaparênteseseregrasdeprecedênciaentre operadores(comoaprecedênciade*sobre+porexemplo),quesãoindispensáveisnanotaçãoin ixa.

Nossoproblema: traduzirparanotaçãopos ixaaexpressãoin ixaarmazenadaemumastringinf. Para simpli icarnossavida,vamossuporque

aexpressãoinféválidaecontémapenasletras,parêntesesesquerdos,parênteses direitos,esıḿbolosparaasquatrooperaçõesaritméticas, todasasoperações(emparticular­e+)têmdoisoperandos, osnomesdasvariáveistêmapenasumaletracada, aexpressãoinfestáembrulhadaemumpardeparênteses(ouseja,oprimeiro

caractereé'('eosdoisúltimossão')'e'\0').

Oalgoritmolêaexpressãoinfcaractere‑a‑caractereeusaumapilhaparafazeratradução. Todo parênteseesquerdoécolocadonapilha.Aoencontrarumparêntesedireito,oalgoritmodesempilhatudo atéoprimeiroparênteseesquerdoinclusive.Aoencontrarum+ouum­ ,oalgoritmodesempilhatudoaté umparênteseesquerdoexclusive.Aoencontrarum*ouum/ ,oalgoritmodesempilhatudoatéum parênteseesquerdoouum+ouum­ . Constantesevariáveissãotransferidosdiretamentedeinfparaa expressãopos ixa. (Vejaumrascunhoempseudocódigo.)

Asvariáveispilhaetsãoglobais. VamossuporqueotamanhoNdapilhaémaiorqueotamanhoda stringinf,eportantonãoprecisamosnospreocuparcompilhacheia. Comoaexpressãoinfestá

11/09/2016

Pilhas

embrulhadaemparênteses,nãoprecisamosnospreocuparcompilhavazia.

#define N 100 char pilha[N]; int t;

// Esta função recebe uma expressão infixa inf // e devolve a correspondente expressão posfixa.

char *infixaParaPosfixa (char *inf) { char *posf; int i, j;

n = strlen (inf); posf = mallocc ((n+1) * sizeof (char)); criapilha ();

empilha (inf[0]);

// empilha '('

for (j = 0, i = 1; inf[i] != '\0'; ++i) { switch (inf[i]) { char x; case '(': empilha (inf[i]); break; case ')': x = desempilha (); while (x != '(') { posf[j++] = x;

x = desempilha ();

}

break;

case '+':

case '­': x = desempilha (); while (x != '(') { posf[j++] = x;

x = desempilha ();

}

empilha (x); empilha (inf[i]) break;

case '*':

case '/': x = desempilha ();

while (x != '(' && x != '+' && x != '­') { posf[j++] = x;

x = desempilha ();

}

empilha (x); empilha (inf[i]); break; default: posf[j++] = inf[i];

}

}

posf[j] = '\0'; return posf;

}

(Poderıámosoperarapilhadiretamente,seminvocarasfunçõesdemanipulaçãodapilha.Oresultado

seriamaiscurtoecompacto,masumpoucomenoslegıv́el.)

VejaoresultadodaaplicaçãodafunçãoinfixaParaPosfixaàexpressãoin ixa (A*(B*C+D)).Atabela registraosvaloresdasvariáveisnoinıćiodecadaiteração:

inf[0

i­1]

pilha[0

t­1]

posf[0

j­1]

(

(

(A

(

A

(A*

(*

A

(A*(

(*(

A

11/09/2016

Pilhas

(A*(B

(*(

AB

(A*(B*

(*(*

AB

(A*(B*C

(*(*

ABC

(A*(B*C+

(*(+

ABC*

(A*(B*C+D

(*(+

ABC*D

(A*(B*C+D)

(*

ABC*D+

(A*(B*C+D))

ABC*D+*

Exercícios3

1.UseafunçãoinfixaParaPosfixaparaconverteraexpressãoin ixa (A+B)*D+E/(F+A*D)+C naexpressão pos ixaequivalente.

2.NafunçãoinfixaParaPosfixa,quetamanhoapilhapodeatingirnopiorcaso,emfunçãoden? Emoutras palavras,qualovalormáximodavariáveltnopiorcaso?Queaconteceseonúmerodeparêntesesesquerdos

naexpressãoforlimitado(menorque6,porexemplo)?

3.ReescrevaafunçãoinfixaParaPosfixasemsuporqueaexpressãoin ixaestáembrulhadaemumparde parênteses.

4.ReescrevaafunçãoinfixaParaPosfixaeasfunçõesdemanipulaçãodapilhademodoqueovetorpilha

sejaalocadodinamicamente.

5.ReescrevaafunçãoinfixaParaPosfixasupondoqueaexpressãopodetercolchetesalémdeparênteses.

6.ReescrevaafunçãoinfixaParaPosfixasupondoqueaexpressãopodenãoserválida.

7.Vꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺ̃ꀺꀺꀺꀺꀺꀺꀺꀺꀺ. Suponhaqueposféumastringnãovaziaqueguardaumaexpressão aritméticaemnotaçãopos ixa.Suponhaqueposfcontémsomenteosoperadores +, ­, * e / (todosexigem doisoperandos).Suponhatambémqueaexpressãonãotemconstantesequetodososnomesdevariáveisna expressãoconsistememumaúnicaletramaiúscula.Suponhaaindaquetemosumvetorvalorquedáos valoresdasvariáveis(todosinteiros):

valor[0]éovalordavariávelA,

valor[1]éovalordavariávelB,etc.

Escrevaumafunçãoquecalculeovalordaexpressãoposf.Cuidadocomdivisõesporzero!

Implementaçãoemvetorcomredimensionamento

Nemsempreépossıv́elpreveraquantidadedeespaçoquedeveserreservadaparaabrigarapilhade modoaevitartransbordamentos. Podemos,então,redimensionarovetortodavezqueapilha icarcheia (comojá izemoscomaimplementaçãode ila).

Exercícios4

1.Mꀺ́ꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺ̃ꀺꀺꀺꀺꀺꀺꀺꀺ(ꀺꀺꀺꀺꀺ̃ꀺ2). Escrevaummódulopilhadechars.cqueimplemente umapilhadecaracteresnumvetorcomredimensionamento. Omódulodeveconterasfunções criapilha, empilha, desempilha, pilhavazia e liberapilha. Trateosparâmetrosdapilhacomovariáveis globaisdomódulo. Escrevatambémumainterfacepilhadechars.hparaomódulo.

Pilhaimplementadaemumalistaencadeada

11/09/2016

Pilhas

Comoimplementarumapilhadecaracteresemumalistaencadeada? Digamosqueascélulasdalistasão dotipocelula:

typedef struct reg {

char

struct reg *prox;

conteudo;

} celula;

Decisõesdeprojeto:Nossalistateráumacélula‑cabeça(eportantoaprimeiracéluladalistanãofazparte

dapilha).Umavariávelglobalapontaráacabeçadalista:

celula *pi;

Otopodapilha icaránasegundacélulaenãonaúltima(porquê?). Asfunçõesdecriaçãoemanipulação dapilhapodementãoserescritasassim:

void criapilha (void) { pi = mallocc (sizeof (celula)); // cabeça pi­>prox = NULL;

}

void empilha (char y) { celula *nova; nova = mallocc (sizeof (celula)); nova­>conteudo = y; nova­>prox = pi­>prox; pi­>prox = nova;

}

char desempilha (void) { char x; celula *p;

p

= pi­>prox;

x

= p­>conteudo;

pi­>prox = p­>prox; free (p);

return x;

}

(Comodehábito,afunçãodesempilhasupõequeapilhanãoestávazia.)

Exercícios5

1.Implementeumpilhaemumalistaencadeadasemcélula‑cabeça.Apilhaserádadapeloendereçodaprimeira

céluladalista(queéotopodapilha).

2.ReescrevaasfunçõesbemFormadaeinfixaParaPosfixaarmazenandoapilhaemumalistaencadeada.

Apêndice:Apilhadeexecuçãodeumprograma

TodoprogramaCconsisteemumaoumaisfunções (sendomainaprimeirafunçãoaserexecutada). Para administrarasinvocaçõesdefunções,ocomputadorusaumapilhadeexecução. (VejaoverbeteCallstack naWikipedia.) Aoperaçãopodeserdescritaconceitualmentedaseguintemaneira:

Aoencontrarainvocaçãodeumafunção,ocomputadorcriaumnovo"espaçodetrabalho",quecontém todososparâmetrosetodasasvariáveislocaisdafunção. Esseespaçodetrabalhoécolocadonapilhade execução(porcimadoespaçodetrabalhoqueinvocouafunção)eaexecuçãodafunçãocomeça

11/09/2016

Pilhas

(con inadaaoseuespaçodetrabalho). Quandoaexecuçãodafunçãotermina,oseuespaçodetrabalhoé removidodapilhaedescartado. Oespaçodetrabalhoqueestiveragoranotopodapilhaéreativadoea execuçãoéretomadadopontoemquehaviasidointerrompida.

Considereoseguinteexemplo:

int G (int a, int b) { int x;

x = a + b;

return x;

}

int F (int i, j, k) { int x;

x = /*2*/ G (i, j) /*3*/;

x = x + k; return x;

}

int main (void) {

int i, j, k, y;

i

= 111; j = 222; k = 444;

y

= /*1*/ F (i, j, k) /*4*/;

printf ("%d\n", y); return EXIT_SUCCESS;

}

Aexecuçãodoprogramaprosseguedaseguintemaneira:

Umespaçodetrabalhoécriadoparaafunçãomainecolocadonapilhadeexecução. Oespaço contémasvariáveislocaisi,j,key. Aexecuçãodemaincomeça.

Noponto1,aexecuçãodemainétemporariamenteinterrompidaeumespaçodetrabalhoparaa

funçãoFécolocadonapilha. Esseespaçocontémosparâmetrosi,j,kdafunção(comvalores111, 222e444respectivamente)eavariávellocalx. ComeçaentãoaexecuçãodeF.

Noponto2,aexecuçãodeFéinterrompidaeumespaçodetrabalhoparaafunçãoGécolocadona

pilha. Esseespaçocontémosparâmetrosaebdafunção(comvalores111e222respectivamente) eavariávellocalx. Emseguida,começaaexecuçãodeG.

QuandoaexecuçãodeGtermina,afunçãodevolve333. OespaçodetrabalhodeGéremovidoda pilhaedescartado. OespaçodetrabalhodeF(queagoraestánotopodapilhadeexecução)é reativadoeaexecuçãoéretomadanoponto3. Aprimeirainstruçãoexecutadaé"x=333;".

QuandoaexecuçãodeFtermina,afunçãodevolve777.OespaçodetrabalhodeFéremovidoda

pilhaedescartado. Oespaçodetrabalhodemain(queagoraestánotopodapilha)éreativadoea execuçãoéretomadanoponto4. Aprimeirainstruçãoexecutadaé"y=777;".

Nonossoexemplo,FeGsãofunçõesdistintas.MastudofuncionariadamesmamaneiraseFeGfossem

idênticas,ouseja,seFfosseumafunçãorecursiva.

Exercícios6

1.Escrevaumafunçãoiterativaquesimuleocomportamentodaseguintefunçãorecursiva.Useumapilha.

int TTT (int x[], int n) { if (n == 0) return 0; if (x[n] > 0) return x[n] + TTT (x, n­1); else return TTT (x, n­1);

}

2.Pꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺ̃ꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺꀺ. (Esteexercıćionãosósimulaofuncionamentodapilhadeexecuçãocomo tambémoprocessamentodasdiretivas#includee#definedopré‑processadordocompiladorC.) Escreva umprogramaquerecebaumarquivodetextoegraveoutroarquivodetextocomoespeci icadoaseguir.Cada

11/09/2016

Pilhas

linhadoarquivodeentradacontémpalavrasseparadasporespaços;aspalavrasquecomeçamcom#são

especiaiseasoutrassãonormais.Oarquivodesaıd́aconteráaspalavrasnormais,emumasólinha,numacerta

ordem.Suponha,porexemplo,queoarquivodeentradacontémasseguinteslinhas(osnúmerosnoinıćiodas

linhaservemapenasdereferênciaenãofazempartedoarquivo):

0 #4 aaa #2

1 bbb

2 CC #4 DDD #1 ee

3 FF #2 #4

4 GG hhh

Entãooarquivodesaıd́a,deveráconter

GG hhh aaa CC GG hhh DDD bbb ee

Comooexemplosugere,aspalavrasespeciassãosubstituıd́aspelalinhadoarquivodeentradacujonúmeroé

dadodepoisdocaractere'#',eissodeveserfeitorecursivamente.Paratornaroexercıćiomaisinteressante,

nãousefunçõesrecursivas.

nãousefunçõesrecursivas. Perguntaserespostas Pꀺꀺꀺꀺꀺꀺꀺ:

Perguntaserespostas

nãousefunçõesrecursivas. Perguntaserespostas Pꀺꀺꀺꀺꀺꀺꀺ:

Pꀺꀺꀺꀺꀺꀺꀺ: ApadronizaçãoANSIdalinguagemCexigequeoscomentáriossejamembrulhadosem /* e */. Porqueoscomentáriossãoindicadospor //nosexemplosacima? Rꀺꀺꀺꀺꀺꀺꀺ: Euachoaconvenção//maissimplesemaisprática.Masrecomendoquevocêobedeçaopadrão ANSIeescreva /* comentário */ paraqueseusprogramassejamaceitospelocompiladorgcccomopção

­ansi.

VejaoverbeteStack(datastructure)naWikipedia

Atualizadoem2016‑04‑01

http://www.ime.usp.br/~pf/algoritmos/

PauloFeo螅ⴰiloff

PauloFeo螅ⴰiloff DCC ‑ IME ‑ USP http://www.ime.usp.br/~pf/algoritmos/aulas/pilha.html 9/10

11/09/2016

Pilhas