Sunteți pe pagina 1din 23

5. Stive.

O stiv este o list la care elementele pot fi inserate i terse la un singur capt (vrful stivei). Elementele sunt terse n ordine invers punerii lor n stiv, motiv pentru care o stiv urmeaz principiul LIFO (Last In First Out) ultimul introdus este primul ters. !e aceea o stiv este folosit uneori pentru inversarea ordinii unui ir de valori. "tiva se folosete pentru a implementa apelul de func#ie i recursivitatea. Specificarea TAD Stiv. !omenii (sorturi)$ "emnturi$ creaz o stiv vid ntoarce % & ', dup cum stiva este sau nu vid returneaz numrul elementelor din stiv - ntoarce vrful stivei, fr a l terge din stiv dac stiva este vid, se produce eroare Stiva, Elem, int new: empty : size : top : Stiva Stiva int Stiva int Stiva Elem

terge elementul din v(rful stivei i returneaz valoarea acestuia dac stiva este vid se produce eroare pop : Stiva Stiva insereaz un element n v(rful stivei push: Stiva Elem Stiva )*iome$ empty (new()) = 1 empty (push(S,e)) = 0 top(push(S,e)) = e top(Stiva_Vida) = eroare pop(push(S,e)) = S pop(Stiva_Vida) = eroare +recondi#ii$ pop(S) top(S) empty(S) empty(S) Interfaa TAD Stiv. Fiierul de interfa# are forma$ !! stiva"h # inter$ata stiva %i$nde$ _S&'V(_ %de$ine _S&'V(_ stru)t stiva* typede$ stru)t stiva +Stiva* !!)onstru)tor Stiva S_,ew(int ))* !!pentru stiva alo)ata )u ta-lou Stiva S_,ew()* !!pentru stiva alo)ata )u lista inlantuita !!destru)tor void S_.elete(Stiva +pS)* !!lun/ime stiva int S_Size(Stiva S)*

!!test stiva vida int S_Empty(Stiva S)* !!punere in stiva !! pre)onditie: stiva neplina void 0ush(Stiva S, void +1)* !!s)oatere din stiva !! pre)onditie: stiva nevida void +0op(Stiva S)* !!inspe)tare element din var$ !! pre)onditie: stiva nevida void +&op(Stiva S)* %endi$ Aplicaii cu stive. %. " se calculeze rezisten#a ec,ivalent, o-#inut prin legarea n serie i n paralel a mai multor rezisten#e. .onfigura#ia este descris postfi*at su- forma$ 2123 opera4ie. "olu#ie$ %in)lude %in)lude %in)lude %in)lude 5stiva"h5 6stdio"h7 6stdli-"h7 6strin/"h7

int main()8 Stiva S* S = S_,ew(30)* dou-le +p21, +p23, +p2* )har des)r930:* int i* /ets(des)r)* $or(i=0* i6strlen(des)r)* i;;) i$(des)r9i:==<2<)8 p2 = (dou-le+)mallo)(sizeo$(dou-le))* s)an$(5=l$5, p2)* 0ush(S, p2)* > else 8 p21 = 0op(S)* p23 = 0op(S)* p2 = (dou-le+)mallo)(sizeo$(dou-le))* i$(des)r9i:==<S<) +p2 = +p21 ; +p23* else +p2=+p21++p23!(+p21;+p23)* 0ush(S, p2)* $ree(p21)* $ree(p23)* > p2 = &op(S)*

print$(5rezistenta e)hivalenta = =?"3l$@n5, +p2)* p2 = 0op(S)* $ree(p2)* i$( S_Empty(S)) print$(5des)riere in)ore)ta@n5)* return 0* > /. 0n palindrom este un ir de caractere, av(nd aceeai semnifica#ie dac este citit nainte sau napoi. "pa#iile i semnele de punctua#ie sunt ignorate. 0n mod de a testa dac un ir este palindrom const n inversarea caracterelor i compararea cu irul dat cele dou secven#e vor tre-ui s fie identice. a scrie#i o func#ie int Este0alindrom()har+ S), care foloseste o stiv pentru a determina dac irul este palindrom. - "crie#i un program care citeste un ir , i scoate spa#iile i semnele de punctua#ie, convertete toate caracterele n litere mici, apeleaz Este0alindrom() i raporteaz rezultatul. "olu#ie$ %in)lude %in)lude %in)lude %in)lude %in)lude 5stiva"h5 6stdio"h7 6stdli-"h7 6strin/"h7 6)type"h7

int Este0alindrom()har+ s)8 Stiva S1, S3* )har +p), +p)1, +p)3* S1 = S_,ew(100)* S3 = S_,ew(100)* int i, d* $or(i=0* i6strlen(s)* i;;)8 p) = ()har+)mallo)(sizeo$()har))* +p) = s9i:* 0ush(S1, p))* > while( S_Empty(S1)) 0ush(S3, 0op(S1))* $or(i=0* i6strlen(s)* i;;)8 p) = ()har+)mallo)(sizeo$()har))* +p) = s9i:* 0ush(S1, p))* > $or(d=0* S_Empty(S1) AA S_Empty(S3)* )8 p)1 = 0op(S1)* p)3 = 0op(S3)* i$(+p)1 = +p)3) d;;* $ree(p)1)* $ree(p)3)* > return d==0 AA S_Empty(S1) AA S_Empty(S3)* >

int main()8 )har +p1 = ()har+)mallo)(B0)* )har +p3 = ()har+)mallo)(B0)* )har +pC = p3* /ets(p1)* !!)onversie in maDus)ule retinand numai litere while(+p1) 8 i$(isalpha(+p1)) +p3;; = toupper(+p1)* p1;;* > i$(Este0alindrom(pC)) print$(5este palindrom@n5)* else print$(5nu este palindrom@n5)* > 1. O e*presie incomplet parantezat con#ine ca termeni constante reale, separate prin operatori i paranteze. O-#ine#i e*presia postfi*at i evalua#i o. 2recerea de la forma infi*at a e*presiei la cea postfi*at presupune opera#iile urmtoare$ a) un termen se pune n irul postfi*at -) o 3(3 se pune n stiva de operatori c) un operator cu prioritate mai mare dec(t a operatorului din v(rful stivei se pune n stiv d) un operator cu prioritate mai mic sau egal cu a operatorilor din v(rful stivei, i descarc pe acetia n irul postfi*at. .(nd prioritatea operatorului a4unge mai mare dec(t a celui din v(rf, se procedeaz ca la c), adic se pune n stiv. e) o 3)3 scoate un operator din stiv i o 3(3. +entru a for#a descrcarea stivei vom scrie ntreaga e*presie ntre / paranteze. !e e*emplu e*presia$ ( + ( E ; F ) ! . # ( E ; G ) se scrie mai nt(i cu o perec,e suplimentar de paranteze e*terioare$ ( ( + ( E ; F ) ! . # ( E ; G ) ) ( + + ( ( ( E ; ( + ( ( # # ( ( E ; ( # ( stiva de operatori sirul post$i1at

+ ! ( (

# ( ( G; #

F ; + . !

Soluie$ +entru trecerea la forma postfi*at vom utiliza o stiv de operatori So. )ceasta este o stiv de iruri de caractere, pentru a uura comunica#ia cu e*presiile infi*at i postfi*at. E*presia infi*at este dat ca un ir de caractere. E*presia postfi*at este tot un ir de caractere, dar preferm s o pstrm, pentru a uura evaluarea, ntr un ta-lou de iruri, n care un element este un termen sau un operator. 5estionarea alocrii de memorie este realizat prin 1 func#ii$ alchr(c) 6 aloc memorie pentru un ir format dintr un caracter (un operator) alstr(p,q) 6 aloc memorie pentru un ir delimitst de pointerii p i 7 alflt(x) 6 aloc memorie pentru un real 2oate aceste func#ii ntorc un pointer la zona alocat.

Evaluarea e*presiei postfi*ate impune folosirea unei stive de termeni St. )ceasta este o stiv de reali. %in)lude %in)lude %in)lude %in)lude %in)lude 6stdio"h7 6stdli-"h7 6strin/"h7 6)type"h7 5Stiva"h5

)har +al)hr()har ))* )har +alstr()har +p, )har +H)* $loat +al$lt($loat 1)* int pri()har op)* int main()8 Stiva So* !+stiva operatorilor+! Stiva St* !+stiva termenilor+! )har i$19100:* !+e1presia in$i1ata+! )har +p$1930:* !+sirul post$i1at+! )har +p, +H, +r* )har )* int i* $loat 1* int l = 0* !+lun/imea sirului post$i1at+! !+$ormarea sirului post$i1at +! So = S_,ew()* 0ush(So, 5(5)* /ets(i$1)* str)at(i$1, 5)5)* $or(p=i$1* p* ) swit)h(+p)8 )ase <(<: r=al)hr(<(<)* 0ush(So, r)* p;;* -reaI* )ase <)<: while(()=+()har+)&op(So)) =<(<)8 r = al)hr())* 0op(So)* p$19l;;: = r* > 0op(So)* p;;* -reaI* )ase <;<:)ase <#<: )ase <+<: )ase <!<: while(pri(+p) 7= pri(+()har+)&op(So)))8 r = al)hr(+()har+)&op(So))* 0op(So)* p$19l;;: = r* > p;;* -reaI* de$ault: i$(isdi/it(+p))8 H = p* while(isdi/it(+H)) H;;* i$(+H==<"<) H;;*

while(isdi/it(+H)) H;;* r = alstr(p, H)* p$19l;;: = r* p = H* -reaI* > > !+evaluarea sirului post$i1at+! $or(i=0* i6l* i;;) i$(isdi/it(p$19i:90:))8 1 = ato$(p$19i:)* 0ush(St, A1)* > else 8 p = ()har+)0op(St)* H = ()har+)0op(St)* swit)h(p$19i:90:)8 )ase <;<: 1 = ato$(p) )ase <#<: 1 = ato$(p) )ase <+<: 1 = ato$(p) )ase <!<: 1 = ato$(p) > 0ush(St, al$lt(1))* > 1 = +($loat+)&op(St)* print$(5=J"3$@n5, 1)* return 0* > )har +al)hr()har ))8 )har +r = ()har+)mallo)(3)* r90: =)* r91: = 0* return r* > )har +alstr()har +p, )har +H)8 )har +r = ()har+)mallo)(H#p;1)* strn)py(r, p, H#p)* r9H#p: = 0* return r* > int pri()har op)8 i$(op==<;< KK op==<#<) return 1* i$(op==<+< KK op==<!<) return 3* return 0* > $loat +al$lt($loat 1)8 $loat +$* $ = ($loat+)mallo)(sizeo$($loat))* +$ = 1* return $* > Implementarea stivelor.
:

; # + !

ato$(H)* ato$(H)* ato$(H)* ato$(H)*

-reaI* -reaI* -reaI* -reaI*

"unt posi-ile dou a-ordri$ implementatorul las n seama utilizatorului gestiunea memoriei )ceasta impune utilizatorului, ca naintea fiecrei opera#ii de punere n stiv$ s aloce dinamic memorie pentru datele care se vor pune n stiv s plaseze datele n memoria alocat dinamic !up scoaterea datelor din stiv i folosirea lor, utilizatorul va eli-era memoria alocat dinamic, pentru a preveni ;scurgerea (risipa) de memorie; implementatorul se ocup i de gestiunea memoriei +entru a putea aloca i eli-era memorie, implementatorul va tre-ui s tie cantitatea de memorie alocat sau eli-erat (sizeo$(tip)). )ceast informa#ie este preluat su- forma unui parametru, transmis, de e*emplu prin constructor, la ini#ializarea tipului a-stract de date. a) Implementare cu tablouri, cu estiunea memoriei fcut !e utili"ator.
Stiva S

struct stiva v 3

cap 10

data 0 1 3.5 4.2 6.25 9

Stiv alocat cu tablou de pointeri <n implementarea cu ta-louri vom face distinc#ia ntre capacitatea stivei 6 dimensiunea ma*im a stivei i dimensiunea stivei, care precizeaz numrul efectiv de elemente din stiv. .onstructorul va avea ca parametru capacitatea stivei ), i va aloca pentru stiva vid ) pointeri. !! stiva") # implementare stiva )u ta-louri %in)lude 6assert"h7 %in)lude 6stdio"h7 %in)lude 6stdli-"h7 %in)lude 6strin/"h7 %in)lude 5stiva"h5 !! stru)t stiva8 int v* !!var$ stiva int )ap* !!)apa)itate stiva void ++data* !!ta-lou de pointeri >* !!var$ul este plasat deasupra ultimului element !!)onstru)tor # alo)a ) elemente
=

Stiva S_,ew(int ))8 Stiva S* S = (Stiva)mallo)(sizeo$(stru)t stiva))* S#7)ap = )* S#7v = 0* S#7data = (void++)mallo)()+sizeo$(void+))* return S* > !!destru)tor # eli-ereaza memoria o)upata de stiva void S_.elete(Stiva +pS)8 int i* $or(i=0* i6(+pS)#7v* i;;) $ree((+pS)#7data9i:)* $ree((+pS)#7data)* $ree(+pS)* > !!$un)tie de a))es # dimensiune stiva int S_Size(Stiva S) 8 return S#7v* > !!$un)tie de a))es # test stiva vida int S_Empty(Stiva S)8 return S#7v == 0* > !!modi$i)ator # pune un element in stiva !! pre)onditie stiva neplina void 0ush(Stiva S, void +1)8 assert(S#7v 6 S#7)ap)* !! veri$i)are pre)onditie S#7data9S#7v: = 1* S#7v;;* > !!modi$i)ator # s)oate un element din stiva si#l intoar)e !! pre)onditie stiva nevida void +0op(Stiva S)8 assert(S#7v 7 0)* !!veri$i)are pre)onditie S#7v##* void +1 = S#7data9S#7v:* return 1* > !!$un)tie de a))es # intoar)e elementul din var$ul stivei !! pre)onditie stiva nevida void +&op(Stiva S)8 assert(S#7v 7 0)* return S#7data9S#7v#1:* > !!veri$i)are pre)onditie

b# Implementare cu liste $nlnit, cu estiunea memoriei fcut !e utili"ator.

>

Stiva S

struct stiva v

3 struct nod

lung

data

next

3.5

4.2

6.25

Stiva alocata dinamic cu lista inlantuita

"e definete mai nt(i un nod al listei$ stru)t nod 8 void +data* stru)t nod +ne1t* >* i structura stiv$ stru)t stiva8 stru)t ,od +v* int lun/* >* Stiva S_,ew ()8 Stiva S = (Stiva)mallo)(sizeo$(stru)t stiva))* S#7v = 0* S#7lun/ = 0* return S* > int S_Empty(Stiva S) 8 return S#7lun/==0* > int S_Size(Stiva S)8 return S#7lun/* > void +&op(Stiva S)8 assert( S_Empty(S))* return S#7v#7data* > void 0ush(Stiva S, void +1)8
?

>

stru)t nod +nou=(stru)t nod+)mallo)(sizeo$(stru)t nod))* nou#7data = 1* nou#7ne1t = S#7v* S#7v = nou* S#7lun/;;*

void +0op(Stiva S)8 assert( S_Empty(S))* stru)t nod +sters = S#7v* void +1 = sters#7data* S#7v = sters#7ne1t* $ree(sters)* S#7lun/##* return 1* > %robleme propuse. %. "crie#i un program care foloseste o stiv pentru a verifica nc,iderea corect a parantezelor ntr o e*presie. E*presia const dintr o linie av(nd p(n la >' de caractere i con#ine 8 tipuri de paranteze$ 8 > 9 : 6 7 ( ) "e consider c e*presia este parantezat corect, dac la nc,iderea unei paranteze de un tip ultima parantez desc,is ntalnit s fie de acelai tip. )stfel e*presia 8(9E6F76.7(E)G: (L)> este corecta, n timp ce 8(9E>: nu este corecta. +rogramul va citi mai multe e*presii i va determina dac sunt corect parantezate. !atele se termin printr un punct. "e va folosi o stiv de caractere. /. Folosi#i o stiv pentru a simula o main simpl de adunat. +rogramul citeste umere reale i le pune n stiva. La citirea caracterului 3@3 se scot numerele din stiva, se adun i se afiseaz rezultatul. <n plus maina recunoaste urmatoarele instruc#i uni$ 3,3 anuleaz ultima intrare 3.3 anuleaz toate intrarile (sterge stiva). 1. "crie#i un program av(nd ca intrare o e*presie infi*at, care are ca ieire e*presia postfi*at ec,ivalent. Intrarea poate con#ine numere, varia-ile, opera#iile aritmetice @, ,A,& i paranteze. E*presiile nu sunt complet parantezate, ordinea de evaluare fiind dat de preceden#a operatorilor. 8. +entru afiarea vertical a unui numr ntreg (c(te o cifr pe r(nd) se poate folosi o stiv n care se vor depune resturile mpr#irilor repetate la %'. "crie#i o func#ie avnd ca argument un numr ntreg, care l afieaz vertical, folosind o stiv. "crie#i o func#ie recursiv av(nd acelai efect ca func#ia de mai sus. 9. +entru afiarea unui numr ntreg n ntr o alt -az E se poate folosi o stiv n care se pun resturile par#iale ale mpr#irii repetate a numrului cu E. "crie#i un program care citete un numr ntreg i pozitiv i o -az 36=E6=M i afieaz reprezentarea numrului n -aza E. !efini#i o func#ie pentru afiarea rezultatului astfel nc(t s putem folosi -aze ntre / i %: "crie#i o func#ie recursiv pentru afiarea unui numr ntreg zecimal n n -aza E.

%'

:. Implementa#i comanda veri$ta/ nume$ care verific dac fiierul BCL cu numele nume$ are marca4ele im-ricate corect. 0n fiier BCL este un fiier te*t care con#ine diverse iruri de caractere ncadrate de marca4e. 0n marca4 (DtagD) este un ir ntre parantezele ascu#ite 363 i 373. Carca4ele se folosesc n perec,i$ un marca4 de nceput (e*$ 6a7) i un marca4 de sf(rit (e*$ 6!a7). +erec,ile de marca4e pot fi incluse unele n altele. E*emplu$ 6a7 """ 6-7 """ 6!-7 """ 6!a7" Eu sunt permise construc#ii de forma$ 6a7 """ 6-7 """ 6!a7 """ 6!-7" Indicaie: Fiierul poate fi citit complet n memorie sau prelucrarea se poate face linie cu linie. Int(lnirea unui marca4 de nceput, pune numele marca4ului n stiv. La nt(lnirea unui marca4 de sf(rit se scoate v (rful stivei i se compar numele marca4ului de sf(rit cu numele marca4ului din v(rful stivei. !ac difer marca4ele nu sunt im-ricate corect. =. O e*presie sim-olica complet parantezata contine ca termini litere, separate prin operatori si paranteze.+entru a o-tine e*presia postfi*ata se procedeaza astfel$ o litera se pune in sirul postfi*at un operator sau 3(3 se pune in stiva de operatori o 3)3 scoate un operator din stiva si l pune in sirul postfi*at si scoate de asemeni din stiva o 3(3. In final, daca e*presia a fost scrisa corect, stiva de operatori se va goli. !e e*emplu e*presia$ ((()@F)A(.&!)) (EAF)) ; ( ( ( ( ( + + ( ( ( ( ( ( E ; F ! ( + ( ( + ( # ( E

( ( ( ( ( (

+ ( ( # # ( ( ( ( . ! +

stiva de # ( G + # operatori sir post$i1at

>. " se evalueze o e*presie complet parantezat, tiind c$ to#i termenii sunt pozitivi fiecare operator se aplic numai la doi termeni. !e e*emplu e*presia complet parantezat (((3C;N)!O);3)+((CB#3)!13) va fi evaluat la /=. Evaluarea e*presiei presupune folosirea a dou stive, una de numere si cealalta de operatori$ numar push (stiva de numere) operator push (stiva de operatori) '(',' ' se ignora ')' pas de evaluare n2 pop (stiva de numere) n1 pop (stiva de numere) op pop (stiva de operatori) n = n1 op n2 n push (stiva de numere) '\n' oprire ?. 0n circuit integrat de form dreptung,iular con#ine mai multe componente. Fiecare component este accesi-il prin dou terminale scoase pe laturile circuitului, identificate prin

%%

aceeai liter. "crie#i o func#ie av(nd ca parametru un ir de caractere, care identific componentele, n ordinea n care acestea sunt dispuse pe circuitul integrat, func#ie care ntoarce numrul componentelor care se intersecteaz. !e e*emplu pentru circuitul )BF..!EE!BF) se ntoarce /. "e va folosi o stiv.
H H D W D

%/

&. 'o"i.
.oada este o list la care inserrile se fac pe la un capt 6 baza cozii, iar tergerile se fac pe la cellalt capt 6 vrful cozii. .ozile sunt utile n aplica#iile de simulare, n traversarea grafurilor n l#ime, n algoritmi cu ar-ori i grafuri. Ordinea de e*tragere din coad este aceeai cu ordinea de introducere n coad, ceea ce sugereaz i aplica#iile pentru o asemenea structur$ simularea unor procese de servire de tip productor consumator sau vnztor - client. <n astfel de situa#ii coada de ateptare este necesar pentru a acoperi o diferen# temporar ntre ritmul de servire i ritmul cererilor solicitan#ilor (clien#ilor). .ozi de servire se pot forma la comunicarea de date ntre un emi#tor i un receptor care au viteze diferite sau la sta#iile de servire, pentru a memora temporar mesa4e sau cereri de servire care nu pot fi nc satisfcute, dar care nu tre-uie pierdute. Specificarea TAD 'oa!. !omenii$ "emnturi$ new : $ront : -a)I : enH : deH : empty : Foada, Elem, int Foada_VidP Elem Elem Foada Foada int

Foada Foada Foada Elem Foada Foada

)*iome$ $ront(enH(e, Foada_Vida)) = e $ront(deH(H, e)) = Gront(H), $ront(Foada_Vida) = eroare deH(enH(Foada_Vida, e)) = Foada_Vida deH(enH (H, e)) = EnH (.eH(H), e), deH(Foada_Vida) = eroare empty(Foada_Vida) = 1 empty(EnH (H, e)) = 0

dac H nu e vida dac H nu e vida

Operaii specifice co"ilor. .rearea unei cozi vide$ new () .opierea elementului din v(rful cozii fr a l terge din coadG (dac coada este vid se produce eroare)$ $ront(Q) Inserarea unui element n coad$ enH(Q, 1) +reluarea elementului de la inceputul cozii i tergerea lui din coadG (dac coada este vid se produce eroare)$ deH(Q) 2est coad vid$ empty(Q) 2est coad plin$ $ull(Q) Inspectarea elementului de la nceputul cozii. $ront(Q) Inspectarea elementului de la sf(ritul cozii. -a)I(Q)

%1

Interfaa TAD 'oa!. !! Gisierul )oada"h %i$nde$ _Q_R %de$ine _Q_R stru)t )oada* typede$ stru)t )oada +Foada* Foada Q_,ew(int)* Foada Q_,ew()* void Q_.elete(Foada +pQ)* int Q_Empty(Foada Q)* int Q_Gull(Foada Q)* void EnH(Foada Q, void +1)* void +Gront(Foada Q)* void +Ea)I(Foada Q)* void +.eH(Foada Q)* %endi$

!!)onstru)tor )u ta-lou )ir)ular !!)onstru)tor )u lista inlantuita !!destru)tor !!test )oada vida !!test )oada plina !!pune din )oada !!)iteste primul element !!)iteste ultimul element !!)iteste si ster/e Aplicaii cu co"i.

1. Problema lui Josephus$ n copii se aeaz n cerc, se numeroteaz n sens orar cu 1,2,...,n i rostesc o poezie format din ) cuvinte (de tipul Dala -ala portocala...D). Fiecruia, ncep(nd cu primul i se asociaz un cuv(nt din poezie. .el care primete ultimul cuv(nt este eliminat din cerc. Hocul continu, ncep(nd poezia de la urmtorul copil, p(n c(nd se elimin to#i copiii. Folosind numerotarea ini#ial, s se afieze ordinea ieirii copiilor din 4oc. Rezolvare: "e va folosi o coad n care se introduc numerele 1,3,""",n. Iostirea unui cuv(nt din poezie se traduce printr o permutare circular (o scoatere a unui element urmat de o inserare a lui n coad). !up ) permutri circulare, elementul scos nu mai este pus la loc n coad, ci afiat. +rogramul se termin n momentul n care coada a4unge vida. %in)lude 5)oada"h5 %in)lude 6stdio"h7 %de$ine S(T 30 int main()8 )har nume9S(T:9C0:* int np, i, +pD, +pi, ), n* s)an$(5=d5, An)* print$(5,umele )elor =3d persoane@n5, n)* $or (i=0* i6n* i;;) s)an$(5=s5,nume9i:)* !!)iteste numar de )uvinte poezie s)an$(5=d5, A))* !!pune persoanele in )oada Foada Uo) = Q_,ew(n)* $or (i=0* i6n* i;;)8 pi = (int+)mallo)(sizeo$(int))* +pi = i* EnH(Uo), pi)* > while( Q_Empty(Uo))) 8 $or (i=0* i6)#1* i;;) 8 pD = .eH(Uo))* !!permutare )ir)ulara

%8

EnH(Uo), pD)* > pD = .eH(Uo))* !!s)oate ultimul din Do) print$(5=s@n5, nume9+pD:)* $ree(pD)* > >

/. Sortarea pe ranguri (radix sort): +entru a sorta un ir de numere ntregi 1 prin metoda Dradi* sortD se folosesc %' cozi corespunztoare cifrelor ',%,...,?, cozi ini#ial vide. "ortarea are loc n urmtorii pai$ %. +entru fiecare numr din irul 1 se separ cifra din rangul r=0,1,3,""", fie i valoarea cifrei si se distri-uie numrul n coada i. /. "e concateneaz numerele din cozile cifrelor n irul 1. "e repet opera#iile % si / pentru toate rangurile numerelor.Opera#ia se nc,eie n momentul n care s au testat toate rangurile. <n final n irul 1 se vor afla numerele sortate. E*emplu$ X !2"#, 1$%, 2&, "%#, 12$&# 'istri(uire dup) rang * +& 2& +# !2"# "%# 12$&# +% 1$% 'istri(uire dup) rang 1 +2 2& +$ 1$% +& 12$&# +% "%# +" !2"# 'istri(uire dup) rang 2 +* *2& +1 1$% +2 !2"# +$ 12$&# +" "%# 'istri(uire dup) rang $ +* **2& *1$% *"%# +2 12$&# +! !2"# 'istri(uire dup) rang & +* ***2& **1$% **"%# *!2"# +1 12$&# "crie#i o func#ie av(nd ca parametru coada principal, care sorteaz irul prin metoda descris. Rezolvare$ +entru fiecare rang au loc dou opera#ii$ o distri-uire a elementelor irului n cele %' cozi o concatenare a elementelor din cele %' cozi in irul de sortat .ifra din rangul r a unui numr n este$ n ! 10r = 10. Eumrul de ranguri testate reprezint numrul de ranguri al celui mai mare numr din ir.

%9

Func#ia .istri-uie() are ca parametri$ ta-loul de sortat T, lungimea lui n, %' cozi n care se distri-uie numerele orespunztor cifrei dintr un rang dat r. <n momentul n care toate valorile sunt plasate ntr o singur coad, irul este sortat. %in)lude %in)lude %in)lude %in)lude 5QF"h5 6stdio"h7 6stdli-"h7 6math"h7

int ran/ma1(int n, int +T)8 int 1m = T90:* int I, r* $or (I=0* I6n* I;;) i$($a-s(T9I:) 7 1m) 1m = $a-s(T9I:)* $or(r=0* 1m 7 0* r;;,1m!=10) * return r* > void .istri-uie(int n, int+ T, Foada+ QF, int r)8 int n)=0, ind, i, D, +pi* $or(i=0* i6n* i;;)8 int t=T9i:* $or(D=0* D6r* D;;) t != 10* ind = t = 10* i$(Q_Empty(QF9ind:)) n);;* pi = (int+)mallo)(sizeo$(int))* +pi = T9i:* EnH(QF9ind:, pi)* > > void Fole)teaza(Foada+ QF, int+ T)8 int D, i=0, +pi* $or (D=0* D610* D;;) while( Q_Empty(QF9D:))8 pi = .eH(QF9D:)* T9i: = +pi* i;;* $ree(pi)* > > void 2adi1Sort(int n, int+ T)8 int rm1, i, r* Foada QF910:* $or(i=0* i610* i;;) QF9i:= Q_,ew (N)* rm1 = ran/ma1(n, T)* $or (r=0* r6=rm1* r;;)8

%:

.istri-uie(n, T, QF, r)* Fole)teaza(QF, T)* > >

int main()8 int n, i* int +1* s)an$(5=d5, An)* 1 = (int+)mallo)(n+sizeo$(int))* $or(i=0* i6n* i;;) s)an$(5=d5, A19i:)* 2adi1Sort(n, 1)* $or(i=0* i6n* i;;) print$(5=Nd 5, 19i:)* print$(5@n5)* $ree(1)* return 0* > 1. <ntr un depou se afl pe o linie n vagoane, identificate cu numere, ncep(nd de la % p(n la n, i plasate ar-itrar. La ieirea din depou se afl un tria4, format prin ramificarea liniei n p linii paralele, care se reunesc apon ntr o singur linie la peron. "e dorete formarea unei garnituri la peron, cu toate cele n vagoane, cu numere plasate n ordine cresctoare. <n acest stop, vagoanele scoase din depou sunt distri-uite pe liniile de tria4 i de acolo, la linia de peron. +reciza#i comenzile de diri4are pe liniile de tria4 de tipul$ JLinia iK; i apoi cele de formare a garniturii la peron de tipul Jla peronK; . Este posi-il ca garnitura s un poat fi format, caz n care programul afieaz J"topK; i se oprete. E*emplu$
2 1 5 6 3 4

Peron

1 2 3

Linia % Linia / Linia % Linia / Linia 1 Linia 1

1 la peron 1 la peron / la peron % la peron / la peron % la peron

"e dau n, p i numerele celor n vagoane din depou. "e vor folosi cozi i func#iile specifice acestora$

%=

%in)lude 6stdio"h7 %in)lude 6stdli-"h7 %in)lude 5Foada"h5 int main()8 int tren930:, n, p, i, D, plasat, nl$=0, +v* Foada triaD910:* s)an$(5=d=d5, An, Ap)* $or(i=0* i6n* i;;) s)an$(5=d5, Atren9i:)* $or(i=0* i6p* i;;) triaD9i: = Q_,ew()* $or(i=0* i6n* i;;)8 !+ in)ear)a plasarea pe o linie deDa $olosita +! plasat = 0* $or(D=0* D6nl$ AA plasat* D;;) i$(+(int+)Ea)I(triaD9D:) 6 tren9i:)8 plasat = 1* EnH(triaD9D:, Atren9i:)* print$(5Vinia =3d@n5, D)* > i$( plasat)8 i$(nl$ 6 p)8 nl$;;* plasat = 1* EnH(triaD9nl$#1:, Atren9i:)* print$(5Vinia =3d@n5, nl$)* > else 8 print$(5nu putem plasa@n5)* return 0* > > > $or(i=0* i6nl$* i;;) while( Q_Empty(triaD9i:))8 v = (int+).eH(triaD9i:)* print$(5=3d la peron@n5, +v)* > return 0* >

%>

Implementarea co"ilor. a# Implementare cu tablou circular !e lun ime fi(. .oada este pstrat ntr un ta-lou data, alocat la ini#ializarea cozii, la o valoare fi*at ) i accesat prin doi indici$ v indicele primului element din coad (v(rful cozii) - indicele ultimului element din coad (-aza cozii) !ac indicii v i - marc,eaz primul, respectiv ultimul element din coad, atunci coada cu un element ar fi caracterizat prin condi#ia v==-, iar coada vid ar avea v naintea lui -, adic avans(-)==vG pe de alt parte coada plin ar fi caracterizat prin aceeai condi#ie i nu am putea face distinc#ia ntre cele dou situa#ii. +entru a disemina ntre cele dou situa#ii (coad vid & coad plin) unul dintre indici nu va indica un element ci o pozi#ie neocupat (dup ultimul element pus sau naintea primului scos) ceeace ar face coada s nu fie utilizat la ntreaga sa capacitate ). +utem evita pro-lema de mai sus dac pstrm numrul de elemente n din coad . Ini#ial coada este vid, av(nd v=0, -=0 i n=0 Ltergerea unui element se poate face numai dintr o coad nevid (n caz contrar se produce o eroare) i se traduce prin v;; i n## )dugarea unui element este posi-il dac nu s a umplut coada i (n 6 )) i se reprezint prin data9-;;:=1 i n;;" Inserarea i tergerea repetat de )#1 ori duce la imposi-ilitatea folosirii cozii, dei ea este vid. "olu#ia o constituie utilizarea unui ta-lou circular, la care cei doi indici avanseaz modulo )$ v=(v;1) = ) -=(-;1) = ) .aracterul circular permite reutilizarea loca#iilor eli-erate prin e*tragerea unor valori din coad. .(mpul - (ultim) con#ine indicele din vector unde se va aduga un nou element, iar v (prim) este indicele primului (celui mai vec,i) element din coad. Cemorarea numrului de elemente e*istente la un moment dat n coad ne permite s deose-im situa#iile de coad goal si coad plin, am-ele caracterizate prin valori egale pentru indicii v i -. (dac nu s ar pstra n, pentru a face distinc#ie ntre cele dou situa#ii limit, ar tre-ui ca indicele b s fie situat dup ultimul mereu introdus (nu ar indica o valoare) i capacitatea cozii ar fi )#1 n loc de ). !imensiunea cozii se calculeaz ca ()#v;-)=) sau mai simplu n. Opera#iile se realizeaz n timp constant (comple*itate W(1)).

%?

"oada #

struct coada data

0 v 1 3 b 6 6 c 3 ! n 3 9 2 5 5 4 2

"oada implementata cu tablou circular

!!'mplementare )oada )u ta-lou )ir)ular Foada") %in)lude 5Foada"h5 %in)lude 6assert"h7 %in)lude 6stdli-"h7 stru)t )oada 8 int v* int -* int n* int )* void ++data* >* !!var$ (in)eput) )oada !!-aza (s$arsit) )oada !!numar de elemente din )oada !!dimens"memorie alo)ata !!ta-lou elemente

Foada Q_,ew(int ))8 Foada Q* Q=(Foada)mallo)(sizeo$(stru)t )oada))* Q#7v = Q#7- = Q#7n = 0* Q#7) = )* Q#7data = (void++)mallo)()+sizeo$(void+))* return Q* >

/'

int Q_Empty(Foada Q) 8 return Q#7n == 0* > int Q_Gull(Foada Q) 8 return Q#7n == Q#7)* > void EnH(Foada Q, void +1)8 assert( Q_Gull(Q))* Q#7data9Q#7v;;: = 1* i$(Q#7v == Q#7)) Q#7v = 0* Q#7n;;* > void +.eH(Foada Q)8 assert( Q_Empty(Q))* void +1 = Q#7data9Q#7-;;:* i$(Q#7- == Q#7)) Q#7- = 0* Q#7n##* return 1* > void +Gront(Foada Q)8 assert( Q_Empty(Q))* return Q#7data9Q#7-:* > b# Implementare cu list $nlnuit. )m folosit aceeai conven#ie ca i n cazul stivelor$ constructorul cozii are ca parametru capacitatea cozii pentru implementarea cozii cu ta-lou circular i nu are parametri, la implementarea cozii cu list nln#uit.
"oada #

struct coada ultim

prim

struct nod lung 3 data next

$mplementarea co%ii cu lista inlantuita

%in)lude 5Foada"h5 %in)lude 6stdli-"h7 %in)lude 6assert"h7 stru)t nod8 void +data*

/%

>*

stru)t

nod +ne1t*

stru)t )oada8 int lun/* stru)t nod +prim* stru)t nod +ultim* >* Foada Q_,ew ()8 Foada Q=(Foada)mallo)(sizeo$(stru)t )oada))* Q#7lun/=0* Q#7prim=Q#7ultim=0* return Q* > int Q_Size(Foada Q)8 return Q#7lun/* > int Q_Empty(Foada Q)8 return Q#7lun/==0* > void +Gront(Foada Q)8 assert( Q_Empty(Q))* return Q#7prim#7data* > void +Ea)I(Foada Q)8 assert( Q_Empty(Q))* return Q#7ultim#7data* > void EnH(Foada Q, void +1)8 stru)t nod +nou = (stru)t nod+)mallo)(sizeo$(stru)t nod))* nou#7data = 1* nou#7ne1t = 0* i$(Q#7ultim==0) Q#7prim = nou* else Q#7ultim#7ne1t = nou* Q#7ultim = nou* Q#7lun/;;* > void +.eH(Foada Q)8 assert( Q_Empty(Q))* void +1 = Q#7prim#7data* stru)t nod +sters = Q#7prim* Q#7prim = Q#7prim#7ne1t* i$(Q#7prim==0) Q#7ultim = 0* $ree(sters)* Q#7lun/##* return 1* >

//

%robleme propuse. %. O coad con#ine elementele a1, a3,""",an cu a1 n fruntea cozii i an n spatele cozii. "crie#i un algoritm cu comple*itate W(n) care plaseaz aceste elemente ntr o stiv, cu a1 n v(rful stivei i an n -aza stivei, pstr(nd ordinea relativ a elementelor. "e vor folosi numai opera#iile specifice tupurilor de date a-stracte stiv i coad. !intr un fiier te*t, s se afieze liniile care reprezint palindroame. In acest scop se pun caracterele litere dintr o linie, convertite n ma4uscule, ntr o stiv i ntr o coad. "e descarc stiva i coada i se numr diferen#ele. !ac nu e*ist diferen#e, am gsit un palindrom.

/1

S-ar putea să vă placă și