P. 1
Pascal

Pascal

|Views: 27|Likes:
Published by Bobe Danut

More info:

Published by: Bobe Danut on Jun 07, 2013
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

03/17/2014

pdf

text

original

Sections

  • 1.1. adaugarea primului element presupune parcurgerea urmatoarelor etape:
  • 1.2.1. înaintea primului element:
  • 1.2.2. dupa ultimul element:
  • 1.2.3. dupa elementul p^:
  • 1.2.4. înaintea elementului p^:
  • 2.1. ALGORITMUL LUI KRUSKAL
  • 2.2. ALGORITMUL LUI PRIM
  • 3.1. REPREZENTAREA ARBORILOR BINARI
  • 3.2. CREAREA SI TRAVERSAREA UNUI ARBORE BINAR
  • 3.3. APLICATII ALE ARBORILOR BINARI
  • 4.1. ALGORITMUL LUI DIJKSTRA
  • 4.2. ALGORITMUL LUI ROY-FLOYD
  • 5. Stergerea elementului minim dintr-o lista ( LISTA SIMPLU ÎNLANTUITA ):
  • 6. Forma poloneza a expresiilor aritmetice:
  • 7. Ioan Tomescu
  • 8. Tudor Sorin

TIPURI DE STRUCTURI DE DATE SI APLICATII

STRUCTURI DINAMICE DE DATE

O mare importanta în programarea si utilizarea calculatoarelor o are modul în care se face organizarea datelor. De cele mai multe ori , în aplicatii , datele se prezinta sub forma unor multimi sau colectii , iar prelucrarea lor nu poate fi conceputa fara o organizare corespunzatoare. Organizarea datelor este un proces complex în care stabilirea structurilor logice si fizice reprezinta elemente fundamentale de care depinde, în mare masura, însasi eficienta prelucrarii. O data care apare ca o entitate indivizibila, atât în raport cu informatia pe care o reprezinta, cât si în raport cu procesorul care o prelucreaza, se numeste data elementara sau scalara. O colectie de date pe care s-a definit o structura si pentru care s-au stabilit procedee de înregistrare si identificare a componentelor se numeste structura de date. Componentele unei structuri de date pot fi date elementare sau alte structuri de date care sunt identificate si selectate prin nume (identificatori), sau prin pozitia pe care o ocupa în structura. Un tip de date defineste atât o multime de valori cât si o multime de operatii ce se pot efectua cu aceste valori. Fiecarei date i se asociaza un tip unic. Astfel, datele ce pot fi prelucrate în programele scrise în limbajul Turbo Pascal pot fi clasificate astfel: 1. Tipuri de date simple ( elementare, scalare) : 1.1. Tipuri de date predefinite: 1.1.1. Întregi 1.1.2. Reale 1.1.3. Booleene 1.1.4. Caracter 1.2. Tipul de date enumerare 1.3. Tipul de date subdomeniu (interval) 2. Tipuri de date compuse (structurate) : 2.1. Tipul de date tablou (array) 2.2. Tipul de date sir de caractere (string) 2.3. Tipul de date multime (set) 2.4. Tipul de date înregistrare (record) 2.5. Tipul de date fisier (file) 3. Tipul de date pointer 4. Tipul procedural
1

Tipurile de date structurate sunt agregari ale unor tipuri deja definite, simple sau structurate, standard sau definite de utilizator. Deci, din punct de vedere al complexitatii lor, datele se pot clasifica în date elementare si date structurate. O alta clasificare a datelor poate fi facuta d.p.d.v. al alocarii memoriei. Acestea pot fi grupate în date alocate static si date alocate dinamic. Procesul de alocare dinamica a memoriei permite ca în timpul executiei programului sa poata fi create, utilizate si distruse anumite variabile numite variabile dinamice. Structurile dinamice de date sunt structuri de date al caror numar de componente se modifica în timpul executarii programului (dimensiunea programului creste si/sau descreste). Structurile dinamice sunt mult mai flexibile decât cele statice si extrem de avantajoase acolo unde este necesara aceasta flexibilitate. O structura dinamica poate avea toate elementele structurate pe un singur nivel, caz în care se numeste lista liniara, poate avea elementele structurate pe mai multe niveluri, caz în care se numeste arbore, sau poate cuprinde elemente care nu pot fi grupate pe niveluri, putând exista legaturi între oricare elemente, structura numinduse în acest caz retea sau graf.
LISTA ARBORE

GRAFURI NEORIENTATE

GRAFURI ORIENTATE

2

Am ales ca tema pentru aceasta lucrare structurile dinamice de date deoarece ele îsi gasesc utilitatea într-un mare numar de domenii. Atât listele cât si grafurile ( acestea incluzând si arborii ) sunt folosite în foarte multe aplicatii. Grigore Moisil spunea : ”Azi teoria grafurilor a devenit o disciplina majora, desi nu-si gaseste locul într-o clasificare dogmatica a capitolelor matematicii. Folosirea teoriei grafurilor în domenii variate, de la chimie la economie, de la studiul retelelor electrice la critica textelor si la politica, îi dau azi un prestigiu de care cel ce clasifica stiintele trebuie sa tina seama.” Listele sunt utilizate în mai multe domenii de activitate, folosirea lor fiind indispensabila: liste cu personalul unei întreprinderi, liste cu materiale cumparate sau produse vândute, cererile catre o anumita informatie ,într-o retea computerizata de baze de date, sunt memorate într-o lista, scanarea memoriei pentru cautarea unor virusi poate fi tratata ca si cautarea unei secvente într-o lista etc. Arborii sunt utilizati si ei în multe domenii: chimie organica, fizica etc . Astfel, ei pot fi utilizati în diverse clasificari , în sortari etc. Structurile dinamice de date ofera elevilor posibilitatea de a rezolva un mare numar de probleme cu aplicatii practice. În aceasta lucrare vor fi prezentate listele, arborii si grafurile orientate si neorientate. La Liste – vor fi date , pentru toate tipurile de liste, definitiile, reprezentarile grafice, operatiile cu liste (crearea, stergerea, parcurgerea, adaugarea), procedurile respective (pentru un exemplu dat) si aplicatii cu fiecare tip de lista. La Grafurile neorientate - se vor defini notiunile necesare în rezolvarea problemelor ce utilizeaza grafurile , se vor trata reprezentarea grafurilor neorientate, parcurgerea lor si se vor prezenta câteva aplicatii . La Arbori – se vor defini notiunile ce vor fi utilizate si se vor trata în special arborii binari si problema arborelui partial minim. La Grafurile orientate - se vor defini noile notiuni, se va trata reprezentarea grafurilor orientate si probleme de drumuri în grafuri. Se vor trate algoritmii de baza: Dijkstra, Roy-Floyd, Roy-Warshall si metoda drumului citic într-un graf de activitati. În capitolul cu aplicatii va fi prezentat si un program de desenare a arborilor binari cu un numar fixat de vârfuri.

3

Probleme apar si la însusirea metodelor de rezolvare a problemelor care necesita în modelare grafuri. Acest lucru se realizeaza prin proiectarea didactica prin care vor fi stabilite obiectivele generale. Pentru aceasta el va trebui ca. Profesorul de informatica trebuie sa valorifice potentialul formativ-creativ al disciplinei. precum si utilizarea unor metode si mijloace de învatamânt adecvate. constientizarea si ierarhizarea unor obiective generale si specifice adaptate particularitatilor de vârsta ale elevilor. de a dezvolta flexibilitatea ei. Aceste probleme apar din mai multe motive. care vor fi conforme cu continutul programei scolare si a obiectivelor specifice. Procesul de învatamânt este un proces formativ-educativ care influenteaza dezvoltarea personalitatii si este o cerinta actuala de pregatire a elevului în vederea integrarii sociale. continutului cunostintelor precum si pregatirea stiintifica si metodica a profesorilor. dezvoltarea motivatiei învatarii si sa realizeze prelucrarea calitativa a cunostintelor predate.CONSIDERATII METODICE Structurile dinamice de date ridica de multe ori probleme elevilor. 4 . Astfel de situatii pot fi însa evitate prin aplicarea de catre profesor a unor principii ale procesului de învatamânt. de a forma deprinderi si atitudini conform continutului de idei. profesorul trebuie sa aleaga si sa utilizeze metode de activizare a elevilor. printre care: Ø Principiul participarii active si constiente a elevilor la procesul de învatamânt Ø Principiul sistematizarii si continuitatii Ø Principiul accesibilitatii cunostintelor si deprinderilor Ø Principiul intuitiei Ø Principiul pasilor mici Ø Principiul progresului gradat al performantelor în pregatire Ø Principiul conexiunii inverse(feed back-ului). sa aplice tratarea diferentiata. O alta greseala pe care o fac frecvent elevii este confundarea operatiilor specifice fiecarui tip de lista. Profesorului de informatica îi revine misiunea de a realiza ore cu un grad mare de eficienta. Una dintre cele mai importante conditii pentru reusita predarii în scoala a unei discipline o constituie structurarea. tinând cont de principiile de mai sus . In învatamântul informatic se aplica mai multe principii ale procesului de învatamânt. odata cu stabilirea obiectivelor generale si specifice. Pentru o proiectare metodologica eficienta. posibilitatea acesteia de a structura gândirea. a afirmarii personalitatii fiecaruia. Unul dintre aceste motive se datoreaza neîntelegerii corecte a relatiei dintre variabila dinamica si variabila de tip reper (referinta) atasata variabilei dinamice. sa realizeze o proiectare corecta a tuturor actiunilor si sa realizeze aplicarea lor eficienta în activitatea de predare-învatare propriu-zisa.

moment al lectiei care are ca obiectiv operational crearea starii psihologice favorabile desfasurarii lectiei. Se urmareste captarea atentiei elevilor.fixarea si consolidarea cunostintelor si indicarea temei. Se urmareste obtinerea performantei si sa se asigure feed-back-ul.Din ansamblul mijloacelor si metodelor de învatamânt. Prezentarea continutului nou este bine sa se faca prin activizarea elevilor. -urmatoarele etape sunt. asigura disciplina.anuntarea subiectului lectiei -moment în care profesorul scrie pe tabla titlul lectiei. care sa duca la descoperirea de catre ei însisi a noilor continuturi. o analiza a atingerii lor. în timp ce elevii noteaza si analizeaza. în timp ce elevii îsi pregatesc materialele si desfasoara o actiune de autoorganizare si control propriu. prin rezolvarea unor sarcini de lucru concrete. Comunicarea obiectivelor lectiei nu este importanta. pentru cazul lectiei de dobândire de cunostinte se pot utiliza urmatoarele: v Metode § –de comunicare Ø orale: • expunerea. 5 . pregateste materialele necesare. dupa lectie. În aceasta etapa profesorul desfasoara o activitate de natura organizatorica: noteaza absente. -urmeaza. • explicatia Ø conversative: • conversatia • problematizarea • discutia colectiva § de actiune ♦ ~ prin aplicatii specifice temei ~ instruire prin activitati independente Mijloace ( resurse materiale): Ø Planse didactice Ø Seturi de aplicatii Ø Fise de lucru pentru elevi Ø Culegeri de probleme Ø Proiect didactic Forma de participare este cea colectiva. -un alt moment al lectiei este. Sunt reactualizate notiunile necesare si se comunica noile cunostinte.procesul de predare-învatare -ce presupune comunicarea cunostintelor si dirijarea învatarii. care va face pentru sine. Astfel o lectie poate avea urmatorul mod de desfasurare în conformitate cu obiectivele propuse: -un moment important al lectiei este organizarea clasei . fiind suficient ca aceste obiective sa fie clare pentru profesor.

Scenariul didactic: Aceasta parte a planului de lectie poate fi: Ø Ø Ø Ø Ø Ø Ø Ø Ø Ø Volumul de cunostinte. material didactic. Întrebarile profesorului. Planurile de lectie . Materialul didactic folosit. II. ♦ Data. Prezentam un model orientativ al planului de lectie: I. ci factori variabili care intervin. impunând variante diferite. ♦ Bibliografie. Pregatirea riguroasa a activitatii didactice este foarte importanta pentru asigurarea eficientei orei de curs. La sfârsitul orei se poate face o evaluare sumativa pe baza unor teste orale cu întrebari . Metodele si procedeele utilizate. * Detaliata . sunt instrumente de lucru absolut necesare. ♦ Subiectul lectiei. Modalitatea de evaluare a activitatii. Etapele lectiei. În elaborarea unui plan de lectie se evidentiaza creativitatea. ♦ Scopul lectiei. neexistând scheme prestabilite. ♦ Obiective perfomative( operationale. schematice sau detaliate. I. talentul pedagogic al profesorului. cognitive si afective) ♦ Metode si procedee didactice. aprecieri ale profesorului sau autoaprecieri. Activitatea profesorului si a elevilor. ♦ Mijloace de învatamânt. ♦ Tipul de lectie. stabilind: * Schematica. Ø Problemele mai importante 6 . rezultate la teste. ♦ Clasa. Date generale: ♦ Obiectul. Timpul acordat fiecarei secvente din lectie. imaginatia. cuprinzând: Ø Etapele lectiei. Schemele care vor fi prezentate. Exercitiile de rezolvat.Evaluarea rezultatelor este un moment important al lectiei si consta în notare.

metode de investigare si comunicare a rezultatelor scolare pentru fiecare elev. sa-i ajute pe acestia sa faca o diagnoza a progresului elevilor si sa adapteze actiunile elevilor cu posibilitatile acestora. Evaluarea rezultatelor scolare este o activitate centrala a unui proces de instruire si învatare. Se va urmarii realizarea tuturor obiectivelor propuse. Evaluarea trebuie sa aiba obiective clar definite. în functie de specificul problemei si de resursele calculatorului. prin utilizarea unor metode si mijloace adecvate . cât si obiectivele educationale (cognitive. O evaluare eficienta trebuie sa arate profesorilor daca au fost atinse obiectivele curriculare. respectiv grafuri orientate ♦ Cunoasterea de catre elevi a avantajelor/dezavantajelor diverselor reprezentari ale grafurilor ♦ Formarea capacitatii de a alege din mai multe metode de rezolvare a unei anumite probleme pe cea optima. De asemenea ea trebuie sa orienteze elevii în alegerea celei mai bune cai de afirmare. psihomotorii si afective). Astfel sunt instrumente: 7 . Ea nu poate fi saparata de instruire si de învatare. sa ajute profesorii sa-si evalueze propria activitate si sa furnizeze feed-back-ul catre parinti. în cele mai bune conditii. metode si tehnici eficiente si moderne. ♦ Insusirea de catre elevi a modului de lucru cu structuri arborescente Vor fi stabilite atât obiectivele specifice fiecarui capitol în parte.Obiectivele generale pentru structurile dinamice de date ( conforme cu continutul programei scolare ) sunt urmatoarele: ♦ Fixarea notiunilor de structuri de date ♦ Fixarea notiunilor de alocare statica si alocare dinamica ♦ Formarea deprinderilor de identificare si rezolvare algoritmica a problemelor care necesita în modelare liste liniare înlantuite ♦ Formarea deprinderilor de identificare si rezolvare algoritmica a problemelor care necesita în modelare grafuri neorientate. Evaluarea poate fi: Ø Predictiva (initiala) Ø Formativa (continua) Ø Sumativa (finala) Exista mai multe instrumente de evaluare . profesorul putând alege ceea ce crede ca este mai indicat.

v Traditionale : • probe scrise • probe orale • probe practice v Alternative: • • • • • • • • • Probe scrise Probe orale Probe practice Observarea directa a elevului în timpul activitatii Investigatia Proiectul de cercetare Portofoliul Tema pentru acasa Autoevaluare În Legea Învatamântului se precizeaza urmatoarele : “Idealul eductional al scolii românesti consta în dezvoltarea libera. integrala si armonioasa a individualitatii umane. în formarea personalitatii autonome si creative.” 8 .” “Învatamântul are ca finalitate formarea personalitatii umane.

dezavantaje si mijloace proprii de tratare a operatiilor specifice. Elevii trebuie sa înteleaga. prezentând. tablouri. Se poate începe cu o expunere despre organizarea memoriei calculatorului. Elevii trebuie sa înteleaga motivatia utilizarii structurii dinamice si avantajele pe care le ofera folosirea acestora. Dupa rezolvare le complicam putin problema. lista candidatilor la un examen de admitere. a memoriei calculatorului sau a spatiului de pe disc(discheta). trebuie explicat elevilor ca acestea pot fi implementate folosind doua modalitati relativ distincte. Crearea unei liste folosind alocarea dinamica a memoriei presupune o structura mult mai flexibila. avantaje . Tema face parte din capitolul “Structuri de date înlantuite” si urmeaza dupa capitolul “Alocare dinamica”. Deci tablourile se vor folosi pentru acele liste în care se cunoaste numarul maxim de componente. 9 .numarul componentelor variaza. se va reaminti tipul referinta( reper) si modul cum poate fi alocata memoria pentru o variabila. Tratarea listelor se poate face folosind tablouri statice sau structuri dinamice de date înlantuite. Se va preciza ca tablourile statice permit crearea unei liste cu un numar de componente limitat de dimensiunea tabloului. Pentru a expune elevilor utilitatea acestei structuri de date este nevoie de a enumera unele domenii de activitate în care folosirea listelor este indispensabila: liste cu materiale . din acest motiv. Pentru studierea acestei teme . dar relativ mai greu de exploatat. fiecare în parte. modalitatea de a alege . pentru rezolvarea unei probleme. elevilor trebuie sa li se reaminteasca notiuni legate de : tipul record. pe când structurile dinamice de date se folosesc acolo unde nu se cunoaste de la început numarul componentelor. Referitor la construirea si exploatarea listelor. limitata de memoria calculatorului sau spatiul pe disc(discheta). în primul rând. una dintre cele doua implementari ale listelor. I LISTELE CONSIDERATII METODICE Listele se studiaza în clasa a X-a la obiectele: “Programarea calculatoarelor” si la “Aplicatii practice de laborator”. Elevii vor descoperi astfel ideea de baza a structurilor dinamice. marind numarul componentelor . de la notiuni mai simple spre un conglomerat de notiuni.CAP. liste cu personalul dintr-o întreprindere etc. Abordarea listelor prin prisma structurilor dinamice de date este o tema noua pentru elevi si . astfel încât sa depaseasca numarul maxim de elemente ale tabloului. trebuie tratata în mod gradat. Pentru aceasta li se poate propune o aplicatie pe care sa o rezolve cu ajutorul tablourilor. alocare dinamica.

inserarea / stergerea unui element dintr-o anumita pozitie. Deci variabilele reper sunt alocate static si au ca valori adrese ale unor variabile dinamice de un anumit tip. Neavând nume (nefiind declarate într-o sectiune VAR) . variabilele dinamice vor fi referite prin intermediul altor variabile. O variabila dinamica se aloca dinamic într-o zona speciala numita HEAP (gramada) care este eliberata la “distrugerea “ variabilei dinamice. Aspectul dinamic al structurii determina aparitia . datele alocate dinamic pot fi generate sau distruse în timpul executiei programului. cautarea unui element cu anumite caracteristici etc. fiecare componenta mai contine si o informatie suplimentara. numita informatie de legatura. Pentru a usura întelegerea modului de memorare a listei se poate folosi o reprezentare grafica a acesteia. Folosind principiile programarii structurate vom crea functii si proceduri pentru adaugarea unui element. mentionând ca fiecare element este caracterizat de informatia utila si de adresa urmatorului element. variabile reper sau referinta. numite . DINAMICA IDENTIF. URM . a caror alocare se realizeaza la început. în faza de compilare si se pastreaza pe durata întrgii executii a programului. parcurgerea unei liste. Tipul reper (referinta) se defineste astfel: TIP REPER ^ IDENTIFICATOR DE TIP -unde prin identificator de tip s-a precizat tipul variabilelor dinamice pe care le refera variabila de tipul reper respectiv. Pentru deducerea algoritmilor se va folosi reprezentarea grafica a datelor. profesorul trebuie sa determine elevii sa înteleaga notiunea de lista si sa deduca modalitatea de implementare a listelor cu ajutorul structurilor de tip referinta. a noi componente care trebuie legate în structura dinamica de celelalte componente. Grafic acest lucru se reprezinta astfel: p p^ 10 INF ADR. Spre deosebire de datele alocate static. notata p^. în timp. DE VAR DE TIP REPER ^ Daca variabila reper p are ca valoare adresa unei variabile dinamice. O variabila dinamica se apeleaza prin intermediul tipului reper corespunzator: VAR. Pentru realizarea înlantuirii datelor. pe lânga informatia propriu-zisa. Informatia de legatura cuprinde adresa componentei urmatoare din structura. spunem ca p refera variabila dinamica p^.Facând apel la intuitie si prin analogii cu alte exemple din viata cotidiana. Variabilelor dinamice li se pune în corespondenta un tip referinta în mod biunivoc: variabila reper contine referiri numai la variabila dinamica careia i-a fost pusa în corespondenta (contine adresa acesteia). din acest motiv.

v lista circulara-care poate fi simplu sau dublu înlantuita. aceasta cazând în sarcina programatorului. iar elementele pot fi inserate oriunde în lista. Apelul procedurii: NEW ( p ) -unde p este o variabila de tip reper. Se numeste lista înlantuita o multime dinamica de structuri succesive de acelasi tip si care satisfac una sau mai multe relatii de ordine introduse prin pointeri. v lista liniara dublu înlantuita.parcurgerea se realizeaza începând cu primul element. Apelarea procedurii : DISPOSE ( p ) O lista liniara se poate defini ca o multime finita E de elemente . din unit-ul System. Listele liniare pot fi de mai multe feluri: v lista liniara simplu înlantuita. pe lânga zona de informatie . doua zone de adresa: una pentru elementul anterior si una pentru elementul urmator. E={e1.e2. sau pot fi sterse indiferent de pozitia lor în lista.en} care satisface proprietatile: 1) exista o relatie de ordine între elementele lui E astfel încât oricare e k are un predecesor si un succesor. Alocarea memoriei se realizeaza prin apelul procedurii NEW definita în unitul System. iar fiecare element contine.Crearea unei variabile dinamice presupune: 1) alocarea unei zone de memorie în HEAP pentru variabila dinamica 2) initializarea zonei de memorie corespunzatoare ei. 11 . Eliberarea zonei de memorie ocupata de o variabila dinamica .parcurgerea acestei liste se realizeaza începând cu ultimul element introdus. iar stergerea unui element se poate realiza numai la începutul listei. v stiva. numit vârful stivei. ea obtinându-se inchizând o lista simplu. alocata prin procedura NEW se realizeaza cu procedura DISPOSE .elementul e1 care nu are predecesor si care se numeste capul listei (prim).…. Alocarea memoriei pentru o variabila dinamica nu presupune si initializarea ei. iar operatiile de adaugare si de stergere se realizeaza la un singur capat al listei . 2) exista un element în lista .parcurgerea ei se face într-un singur sens de la primul spre ultimul element. 3) exista un element în lista – elementul en care nu are succesor si care se numeste element terminal( ultim). respectiv dublu înlantuita. adaugarea unui element se poate face numai la sfârsitul listei .parcurgerea ei se poate realiza în ambele sensuri. prin legarea primului element al listei dupa ultimul element al ei. v coada.

toate programele de prelucrare vor trebui sa cuprinda secvente de început prin care sa se exprime faptul ca structura dinamica este vida. ♦ accesul la elementele structurii este asigurat prin intermediul adreselor de legatura. Operatiile specifice tuturor structurilor dinamice sunt: Ø adaugarea unui element în structura –care presupune: ü alocarea dinamica a memoriei pentru noul element ü initializarea noului element alocat ü legarea elementului în structura Ø parcurgerea (traversarea) elementelor structurii.este posibila numai daca structura este nevida si presupune: ü eliminarea elementului din structura prin modificarea adreselor de legatura ( stergere logica) ü eliberarea memoriei ocupate de elementul respectiv( stergerea fizica) 12 . deoarece fiecare element cuprinde adresa elementului urmator. Se va avea grija sa nu se distruga structura si sa nu se piarda adresa primului element al structurii.este necesar sa se cunoasca adresa primului element al structurii (aceasta adresa va fi pastrata într-o variabila de tip reper asociata structurii).Trasaturile comune tuturor structurilor dinamice de date sunt: ♦ ele se dezvolta dinamic pornind de la o structura initial vida.Prelucrarea acestor structuri dinamice se realizeaza cu ajutorul variabilelor reper si a variabilelor dinamice.se utilizeaza o variabila de lucru de tip reper ale carei valori reprezinta adresa elementului curent al structurii. Ø stergerea unui element al structurii.

Operatiile nu sunt dificil de realizat. treptat. În capitolul cu aplicatii se vor da exemple de probleme care folosesc în rezolvarea lor tipurile de liste studiate. fapt care simplifica mult lucrurile. Acest dezavantaj poate fi eliminat daca lista este creata cu doua santinele. acestea reprezentând o alta categorie speciala de liste liniare. Dupa ce elevii vor întelege modul de lucru cu acest tip de lista se poate trece la tratarea listelor de tip coada. Lista liniara dublu înlantuita nu ridica probleme daca elevii înteleg modul în care se leaga elementele atunci când se cunosc adresele elementului precedent si urmator ale fiecarui element din lista. iar stergerea lor nu se poate face decât la începutul listei. însa deranjeaza faptul ca trebuie tratate atâtea cazuri particulare. Lista circulara va fi usor înteleasa de catre elevi . Lista liniara simplu înlantuita poate ridica unele probleme. sa se rezolve probleme cu un grad din ce în ce mai mare de dificultate. daca acestia au înteles modul de lucru cu listele simplu si dublu înlantuite. pentru ca. Parcurgerea listei se poate realiza în ambele sensuri . Pentru fiecare tip de lista se vor oferi exemple cât mai simple. 13 .Pentru o mai usoara întelegere a listelor . este mai bine sa se înceapa tratarea lor cu stiva . numit vârful stivei. deoarece apar mai multe situatii atât la adaugarea unui element în lista cât si la stergerea unui element din lista. Existenta celor doua adrese de legatura simplifica atât operatiile de adaugare cât si pe cele de stergere. deoarece adaugarea si stergerea elementelor acestui tip special de lista se realizeaza la acelasi capat al listei . Se poate prezenta apoi modul de tratare a listelor de tip coada cu ajutorul unei santinele. în care elementele se pot adauga numai la sfârsitul listei. pentru început. fiind o lista simetrica.

STIVA ( L I F O ) Stiva este o lista liniara de un tip special. exceptie facând baza .. în care adaugarea sau scoaterea unui element se face la un singur capat al listei. stive de carti etc.este posibila numai în vârful stivei si presupune urmatoarele etape: alocarea memoriei pentru noul element NEW (p) initializarea zonei de informatie din variabila dinamica p^ : p^. Pot fi oferite elevilor exemple de stive din viata cotidiana : o stiva de lemne . legarea elementului în vârful stivei : p^. Reprezentarea grafica a unei stive: vârf NIL INFO INFO INFO BAZA STIVEI VARFUL STIVEI Conditia de stiva vida este: vârf=NIL Operatii cu stive : Ø Adaugarea unui element . Ei vor întelege astfel ca nu pot adauga un nou element (lemn. carte) decât în vârful stivei si nu vor putea sa scoata din stiva un element decât daca acesta se afla în vârful stivei. mutarea vârfului stivei: vârf := p 14 . a carei informatie de legatura este NIL.info:=…. farfurie. sau Readln (p^.info ) 3. o stiva de farfurii . Primul element introdus se numeste baza stivei.info := vârf 4. Informatia de legatura a fiecarui element din stiva reprezinta adresa elementului pus anterior în stiva. numit vârful stivei.

vârf : reper. se elibereaza memoria ocupata de fostul vârf : Dispose (p) Considerând urmatoarele declaratii: Type reper=^ element.Ø Parcurgerea unei stive. Var p.next 3. next:reper end. dupa principiul : Last In – First Out. next Ø Stergerea unui element din stiva se poate sterge numai elementul din vârful stivei (daca aceasta este nevida) : 1. Parcurgerea se realizeaza cu o variabila de tip reper p care contine adresa elementului curent : se porneste din vârful stivei : p := vârf cât timp stiva nu este vida ( vârf <> NIL) se parcurge elementul curent si se trece la urmatorul element din lista : p := p^. element=record info:string[10]. se salveaza adresa vârfului stivei într-o variabila reper p în vederea eliberarii memoriei: p:=vârf 2. Text : string[10]. putem sa scriem urmatoarele subprograme: 15 . se muta vârful stivei pe elementul urmator celui ce se va sterge : vârf := vârf ^.se vor parcurge elementele listei în ordinea inversa introducerii lor.

readln( text ). Write(‘ introduceti informatia :’). Vârf:=p. 16 . End. Write (‘ introduceti informatia :’). vârf:=p. p^. While text<> ‘’ do Begin New(p). Begin Vârf:=nil. p^. end.info). End. Readln(text). write(‘ introduceti informatia :’). Readln ( text). begin p:=vârf. p:=p^. P^.next end.Crearea stivei: Procedure creare. Adaugarea unui element in stiva: Procedure adaug. while p<>nil do begin writeln( p^.next:=vârf.next:=vârf. begin new(p).info:=text.info:=text. P^. Parcurgerea stivei: Procedure parcurg.

next:reper.info). Begin vârf:=nil. if vârf = nil then writeln (‘s-a tastat enter ‘) else begin write (‘cuvântul inversat este : ’). dispose(p). p : reper. writeln(p^. Begin p:=vârf. vârf:=p end. p^. read (p^. 17 . p:=p^.next:=vârf. Var vârf. p:=vârf. end.litera). End. while not eoln do begin new(p). O problema simpla care ilustreaza modul de lucru cu stiva este cea care inverseaza caracterele unui cuvânt citit de la tastatura dintr-o linie de intrare. writeln end end. Element=record litera:char.next until p=nil.litera). {stiva vida} write(‘ cuvântul: ‘).Stergerea unui element din stiva: Procedure sterg. Program inversare_cuvânt.next. Type reper=^element. vârf:=p^. repeat write(p^.

coada va avea doi pointeri (variabile de tip reper) : prim si ultim. în timp ce variabila reper ultim. Deci. COADA( F I F O ) COADA reprezinta o categorie speciala de lista liniara. pointerul prim va indica valoarea NIL. Reprezentarea grafica a unei cozi : INF INF INF NIL prim ultim Când coada este vida . se realizeaza numai la începutul cozii . are ca valoare adresa ultimului element din lista. Variabila reper prim are ca valoare adresa primului element din lista. la care operatiile se executa doar la un capat al stivei (vârf). iar iesirile sau stergerile . la coada . Operatiile specifice acestei structuri sunt: Ø Ø Ø Ø crearea listei liniare de tip coada adaugarea unui element în structura stergerea unui element din structura parcurgerea (traversarea ) elementelor structurii 18 . Elementul curent a carui adresa este retinuta în variebila reper p.primul servit”. contine cele doua zone : -zona de informatie si -zona de legatura. Si denumirea este semnificativa : F I F O = First In – First Out – adica “primul venit. adaugarile se fac numai la sfârsitul cozii (ca si asezarea unei persoane la rând). Spre deosebire de stiva . Asemanarea cu o coada care se formeaza la un magazin va usura întelegerea acestui tip de lista. Deci conditia de coada vida este : prim=nil .2. în care elementele se adauga la un capat (sfârsit) si se suprima la celalalt (început). spre deosebire de stiva.

sau p^. dupa el nemaifiind nici un element.adaugarea elementelor la sfârsitul cozii.next:=nil. sau Readln( prim^. b) Initializarea elementului alocat prin precizarea continutului zonei de informatie si al zonei de legatura : prim^. Crearea listei de tip coada –presupune : . c) legarea elementului în structura: ultim^.info:= ….info) prim^. 1. va fi si ultimul ) : ultim:=prim. d) variabila ultim primeste ca valoare adresa elementului adaugat. 19 . Readln(p^. fiind singurul element din lista. Adaugarea unui element în coada se poate face numai la sfârsitul cozii. c) variabila ultim va primi ca valoare adresa primului element (acesta. care devine ultimul element din lista: ultim:=p.info) Adresa de legatura a elementului adaugat este NIL deoarece acesta este ultimul element din lista .next:=nil.2.info:=…. Adaugarea primului element presupune parcurgerea urmatoarelor etape : a) Alocarea memoriei pentru primul element: New(prim).1.adaugarea primului element într-o coada vida .. 1.1. dupa ultimul element si presupune parcurgerea urmatoarelor etape: a) Alocarea memoriei pentru noul element : New(p) b) initializarea elementului alocat: p^.next:=p.

2. coada devine vida.next) pâna se ajunge la sfârsitul listei .Se parcurg urmatoarele etape: 1. next:reper end. Stergerea unui element al cozii: presupune stergerea primului element al listei . considerând o lista de tip coada declarata astfel: Type reper=^element.p :reper. se salveaza adresa elementului ce va fi sters : p:=prim.next sfârsit_cât_timp 3. vor fi urmatoarele: 20 . 2. se elimina din structura primul element prin memorarea în variabila reper prim a adresei elementului care urmeaza lui prim. variabila ultim nu exista. text:string[10].Procedurile corespunzatoare acestor operatii. Var prim.Trebuie sa se tina seama de ordinea în care se executa operatiile. element=record info:string[10]. acesta devenind noul prim element: prim:=prim^. se elibereaza memoria ocupata de fostul prim element al cozii : Dispose(p) În cazul în care se sterge unicul element al listei. pentru a nu se pierde informatiile. În pseudocod parcurgerea se realizeaza astfel: p:= prim cât_timp p<>nil executa *se parcurge elementul p^ p:=p^. Legarea noului element în structura presupune existenta variabilei dinamice ultim^. Parcurgerea elementelor unei cozi: se realizeaza pornind de la primul element al listei (p:= prim) si trecând pe rând prin fiecare element (p:=p^.next 3. In cazul în care lista este vida. de aceea nu este necesara legarea elementului în structura. ultim. iar variabila prim va avea valoarea nil.

Parcurgerea cozii: Procedure listare. 21 .Crearea cozii Procedure creare. prim^. p:=p^. ultim^.next:=p ultim:=p end end. p^.info:=text.next until p=nil end end. readln(text).next:=nil. repeat writeln(p^. prim^. Begin Write(‘ dati informatia : ‘). p^.info). If prim=nil {coada este vida} then begin {adaugarea primului element} new(prim).next:=nil. ultim:=prim. end else {adaugare element la sfârsitul cozii} begin new(p).info:=text. begin if prim=nil {coada vida} then writeln (‘coada este vida’) else begin p:=prim.

NIL sant ultim Pentru a se întelege mai bine rolul santinelei. coada poate fi creata cu o santinela ca prim element al cozii. prim:=prim^. O coada vida va cuprinde numai santinela: New(sant). 22 . Locomotivele se identifica printr-un cod. ultim^. dispose(p) end end.intrarea unei locomotive. Un exemplu clasic pentru probleme ce se rezolva utilizând liste de tip coada este problema urmatoare (a carei rezolvare se gaseste în capitolul cu aplicatii): Dispecerizare locomotive Se considera un depou de locomotive cu o singura linie de cale ferata cu o intrare si o iesire. COADA CU SANTINELA Pentru eliminarea testului de coada vida la adaugarea unui element . ultim:=sant. prelucrând comenzi de forma: I.Stergerea unui element din coada Procedure stergere. begin if prim=nil then writeln(‘ lista este vida’ ) else begin p:=prim. Sa se scrie programul care realizeaza dispecerizarea locomotivelor din depou.next. fara a fi considerat consumator (fara a face parte din lista). Santinela este o variabila dinamica a carei zona de informatie este neinitializata si care a fost introdusa ca prim element al cozii în vederea optimizarii operatiilor asupra cozii. se apeleaza la un om de ordine care supravegheaza modul de servire a consumatorilor. pentru bunul mers al lucrurilor .iesirea unei locomotive. L-listarea locomotivelor din depou si S-pentru oprirea programului (si listarea locomotivelor existente în depou). E. se va da ca exemplu o coada formata la un magazin la care .next:=nil.

presupune parcurgerea elementelor cozii.2 se muta santinela pe elementul care ar trebui sters sant:=sant^.2. Adaugarea presupune: 1. next cât_timp p<>nil executa * se parcurge elementul p^ p:= p^. Adaugarea unui element în coada-nu mai are importanta daca lista de tip coada este sau nu vida. 1. sau readln(p^.info).Reprezentarea grafica a unei cozi cu santinela : INFO INFO NIL sant primul element ultim Operatiile corespunzatoare unei cozi cu santinela sunt: 1.Stergerea primului element al unei cozi cu santinela: 3. nu si santinela: p:= sant^.next:=p.next.1 se salveaza adresa santinelei: p:=sant. Parcurgerea elementelor unei cozi cu santinela.3 legarea elementului în structura ultim^.next:=nil.4 initializarea variabilei ultim cu adresa ultimului element adaugat: ultim:=p 2.info:=…. 3. 23 .1 alocarea memoriei pentru noul element: New(p) 1. 3.3 se elibereaza memoria ocupata de fosta santinela Dispose(p). p^. initializarea elementului alocat p^. 1.next sfârsit_cât_timp 3.

Se va nota cu p adresa elementului curent al listei. Ca exemplu de lista liniara se poate da lista copiilor care vor merge într-o excursie. Deci parcurgerea listei se va realiza doar într-un sens si anume de la primul element. indiferent unde s-ar afla ele. a carui adresa este memorata în variabila reper ultim. caz în care pot sa apara doua situatii: ♦ p=ultim ♦ p<>ultim 24 . a carui adresa se gaseste în variabila reper prim spre ultimil element. caz în care pot sa apara doua situatii: ♦ p=prim ♦ p<>prim Ø dupa elementul p^. adaugarea primului element 2. fiecare copil stiind numele (adresa de legatura) copilului care îi urmeaza în lista. Crearea listei presupune doua etape: 1.LISTA LINIARA SIMPLU ÎNLANTUITA Lista linira simplu înlantuita este o lista ale carei elemente pot fi adaugate oriunde în cadrul listei si pot fi sterse . adaugarea celorlalte elemente Un element se poate adauga : Ø înaintea elementului p^ . Reprezentarea grafica a unei liste liniare simplu înlantuita : INFO INFO INFO NIL prim ultim Lista vida presupune îndeplinirea conditiei prim=nil Lista cu un singur element poate fi reprezentata astfel: INFO NIL prim ultim Operatii cu liste liniare simplu înlantuite: 1. Fiecare element al listei contine o parte cu informatia propriu-zisa si o parte cu adresa urmatorului element din lista.

3. c) se leaga elementul în structura: ultim^.1.info). dupa elementul p^: a) se aloca memorie pentru noul element: new(q).2. 1.2. c) se leaga în structura elementul adaugat: p^.2. dupa ultimul element: a) se aloca memorie pentru noul element: new(p). c) legarea noului element în structura: p^. • variabila ultim primeste ca valoare adresa elementului : ultim:=prim.info).info:= … sau readln(prim^. adaugarea primului element presupune parcurgerea urmatoarelor etape: • alocarea memoriei pentru noul element: new(prim). 25 1. b) se initializeaza elementul p^.2.info:=… sau readln(q^. • initializarea noului element: prim^.info:=… sau readln(p^. .1.info:=… sau readln(p^.next:=p. q^. adaugarea unui element : înaintea primului element: a) se aloca memorie pentru noul element : new(p).next:=prim.next:=p^. 1. d) elementul introdus devine ultimul element din lista ultim:=p. p^. 1.info) prim^.2. b) se initializeaza elementul: p^. b) se initializeaza noul element: q^.next:=q.next:=nil.1. d) variabila prim va primi ca valoare adresa elementului adaugat: prim:=p.info).next:=nil.next.

problema adaugarii înaintea elementului p^ este echivalenta cu problema adaugarii dupa q^ . se pierde adresa elementului care urma dupa p^ înainte de adaugarea lui q^. adresa de care avem nevoie pentru a adauga un element înaintea elementului p^.Ordinea celor doua operatii de legare în structura este esentiala.next ultim În acest fel. b) elementul q^ trebuie sa apara în lista înaintea elementului p^ . daca am ajuns la elementul p^. se initializeaza p^. Avem doua solutii: a) se pastreaza adresa elementului precedent lui p^. NIL prim q p=q^. prin urmare.next. daca se executa întâi p^.2. Acest lucru se poate realiza procedând astfel: ü ü ü ü ü se aloca memorie pentru noul element : new(q). daca p este ultimul element : ultim :=q. înaintea elementului p^: Fiecare element al listei contine adresa elementului urmator în lista. se copiaza p^ în noul element notat cu q^: q^:=p^.next:=q .next:=q.info cu valoarea care trebuie adaugata se leaga elementul p^ de q^ : p^. nu mai stim adresa elementului precedent în lista. 1. notând acest element cu q^ si folosim relatia : p:=q^.4. NIL prim p q ultim 26 .

ü se elimina din structura q^.) si eliberam memoria ocupata anterior de acesta.2.next ultim Se parcurg urmatoarele etape: ü se pastreaza adresa elementului precedent q^. elementul urmator (p^. ü se salveaza adresa elementului care trebuie sters p:=q^.next^: q^. Stergerea fizica se realizeaza cu procedura Dispose. Apare necesitatea cunoasterii adresei elementului precedent.next^.next:=q^.next^. legând q^ de p^.next^.next.next ü se elibereaza memoria ocupata de elementul sters : dispose(p) b) mutam în locul elementului care trebuie sters (p^). NIL prim q p =q^. Stergerea unui element din lista –pot sa apara urmatoarele situatii: Ø se sterge primul element din lista Ø se sterge ultimul element al listei Ø se sterge un element oarecare al listei p^ Stergerea logica a elementului p^ presupune eliminarea lui din structura prin legarea elementului precedent lui p^ cu urmatorul sau element.next . Avem doua solutii: a) pastram adresa elementului precedent (q^) si transformam problema stergerii elementului p^ în stergerea elementului q^. NIL prim p q ultim 27 .

3. end. element=record info:string[10]. ultim^.readln(text). var prim. begin prim:=nil. ultim.info:=text.next sfârsit_cât_timp Considerându-se data urmatoarea declarare a unei liste simplu înlantuite: Type reper=^element.next:=nil. ultim:=p. prim^. p^. text:string[10]. 28 . p^.next:=nil.next:=p. ultim^. se vor putea scrie urmatoarele proceduri pentru : Crearea listei : procedure creare.p: reper.next:=nil. end.readln(text). afisând informatia continuta de fiecare element. Parcurgerea listei (afisarea elementelor listei)-se realizeaza de la primul spre ultimul element al listei . write('introduceti textul :'). ultim:=prim end else begin new(p). în cazul în care se doreste afisarea elementelor listei. while text<>'' do begin if prim=nil then begin new(prim). end. next:reper end. write('introduceti textul :').info:=text. prim^. În pseudocod vom avea: p:= prim cât_timp p<>nil executa * se parcurge elementul p^ p:=p^.

29 . ultim:=p. prim:=p. readln(text).next:=nil.Adaugarea unui element înaintea primului element: procedure adaugare_in.next.info:=text. p^. write('introduceti informatia ce se adauga la sfarsit: '). { adaugare la inceputul listei} begin new(p). end. writeln. readln(text). p^. end . end. {adaugare la sfarsitul listei} begin new(p). while p<>nil do begin write(p^.next:=prim. write('introduceti informatia ce se va adauga la inceput: ').info. p:=p^. p^.info:=text. ultim^. begin p:=prim.next:=p.' '). Adaugarea unui element dupa ultimul element: procedure adaugare_sf. Parcurgerea elementelor unei liste: procedure afisare. end. p^.

info<>text do begin p:=q.next. write('introduceti informatia ce se va sterge: '). var q:reper. if q=ultim then ultim:=p. 30 . end. p^. end.Stergerea unui element din lista: procedure sterge. end.next. if p^. q:=q^. while q^.readln(text). Pentru a înlatura dezavantajul creat de numarul mare de cazuri care pot sa apara la tratarea listelor liniare simplu înlantuite se poate crea lista liniara cu santinele. begin p:=prim.info<>text then begin q:=p^. de adaugare în fata primului element sau dupa ultimul. Existenta santinelelor elimina cazurile de lista vida.next.next:=q^. dispose(p). dispose(q).next. end else begin prim:=p^.

next:=sant2 sant1 sant2 Procedurile sunt asemanatoare celor de la lista liniara simplu înlantuita cu deosebirea ca.Lista oarecare cu santinele .info). 31 . locul lor fiind luat de doua variabile de tip reper : sant1 si sant2. Pentru exemplificare se poate rezolva problema stergerii elementului minim dintr-o lista de numere întregi distincte. folosind o lista liniara creata cu doua santinele: sant1 si sant2. Adaugarea înaintea primului element se transforma în adaugarea dupa sant1. respectiv a ultimului element din lista. în locul variabilei prim avem variabila sant1. Conditia de lista vida devine inutila. iar în locul variabilei ultim vom avea variabila sant2. O particularitate apare la parcurgerea listei . while p<>sant2 do begin write(p^.este o lista liniara oarecare în care nu mai avem variabilele prim si ultim . în care erau retinute adresele primului. nu si santinelele: p:=sant1. când se vor parcurge numai elementele listei. Rolul santinelei a fost explicat la tratarea cozii cu santinela. iar adaugarea dupa ultimul element se reduce la adaugarea înaintea lui sant2. Reprezentarea grafica a unei liste cu santinele: sant1 p sant2 Lista vida se reprezinta ca având doar cele doua santinele: new(sant1).next end. new(sant2). sant1^. elemente care nu sunt considerate ca facând parte dintre elementele listei. p:=p^.

LISTA DUBLU ÎNLANTUITA Lista dublu înlantuita este un tip special de lista în care informatia de legatura a fiecarui element cuprinde atât adresa elementului precedent în lista. Reprezentarea grafica a unei astfel de liste poate arata astfel: sant1 INF sant2 În cazul listelor dublu înlantuite cu santinele. Reprezentarea grafica a unei liste dublu înlantuite: prim INF NIL INF ultim INF NIL O componenta a listei va contine trei locatii. respectiv sant2. si listele dublu înlantuite se pot crea cu doua santinele. în locul variabilelor prim si ultim vom folosi variabilele sant1. respectiv a ultimului element din lista. Variabilele prim si ultim vor memora adresa primului. Ca si în cazul listelor simplu înlantuite . cât si adresa elementului urmator.4. sau câmpuri: locatia info contine informatia. locatia pred contine adresa componentei anterioare. 32 . Semnificatia notiunii de santinela se cunoaste de la listele anterioare. iar variabila p retine adresa elementului curent. locatia next contine adresa componentei urmatoare.

Crearea listei dublu înlantuita presupune scrierea în lista a primului element si adaugarea celorlalte elemente ale listei. var prim. Ø stergerea primului element al listei. Ø adaugare dupa ultimul element. Ø stergerea ultimului element al listei. pred:reper. deci numarul de cazuri . Ø adaugare înaintea unui element oarecare p^. v stergerea unui element din lista: Ø stergere la stânga lui p^. v adaugarea unui element în lista: Ø adaugare înaintea primului element. cât si la stergerea unui element din lista .ultim. text:string[10].p:reper. atât la adaugarea unui element . Ø adaugare dupa un element oarecare p^. next:reper end. putem scrie urmatoarele proceduri: 1. De asemenea . Daca lista este creata cu doua santinele . atunci toate elementele listei vor avea un element precedent si un succesor.Operatiile cu listele dublu înlantuite sunt: v crearea listei. ü memorarea informatiei utile si a informatiei de legatura pentru noul element ü variabilele prim si ultim vor primi ca valoare adresa elementului introdus în lista 33 . Presupunând declarata urmatoarea lista: Type reper=^element. Ø stergere la dreapta lui p^. se reduce. Adaugarea primului element presupune: ü alocarea de spatiu pentru noul element. existenta celor doua adrese de legatura în fiecare element al listei dublu înlantuite simplifica mult atât operatiile de adaugare cât si pe cele de stergere . v parcurgerea elementelor listei. element=record info:string[10]. nemaifiind o problema cunoasterea adresei anterioare elementului curent p^.

inf:').next:=nil. begin write(‘ informatia: ‘). p^. Adaugarea unui element în lista dublu înlantuita – pot sa apara urmatoarele situatii: Ø adaugarea unui element la dreapta lui p^ . unde p^ poate fi initial chiar primul element .readln(text). 2.procedure creare. begin write('nr. element a carui înscriere se realizeaza într-un mod diferit de a celorlalte elemente. Prin preocedura de mai sus s-a memorat în lista primul element . prim^. prim^.info:=text.readln(nr). p^. 34 .next:=p. ultim:=p end. se completeaza câmpurile de informatie si de adrese se leaga în structura noul element: ultim^next:=p elementul nou introdus devine ultimul element din lista ultim:=p procedure adaugare_dr ( p:reper ). ultim:=prim end.i:integer.next:=nil. var nr. Se parcurg urmatorii pasi: ü ü ü ü se aloca memorie pentru noul element: new(p). p^.readln(text). new(p). end.pred:=ultim.pred:=nil. new(prim). ultim^. prim^. for i:=1 to nr do {nr reprezinta nr informatiilor introduse} begin write('adaug informatia: ').info:=text.

p^.pred:=p^. p^.info:=text.se parcurg aceleasi etape ca la adaugarea la dreapta .pred:=p.pred:=nil. q^. end. begin new(q).next:=p. p^. procedure adaug_st(p:reper).pred^.caz asemanator cu adaugarea la dreapta lui p^. atunci când p=ultim 35 . q^.next:=prim. write('adaug informatia :').pred:=q. p^. Faptul ca avem adresa elementului anterior face ca adaugarea la stânga sa fie asemanatoare adaugarii la dreapta lui p^. begin new(p). prim:=p. write(‘introduceti informatia : ‘).next:=q.pred. procedure adaug_in. prim^.readln(text).info:=text. p^. Ø adaugarea la sfârsitul listei –presupune adaugarea dupa ultimul element. q^. var q:reper. end.readln(text).Ø adaugarea unui element la stânga lui p^. Ø adaugarea unui element la începutul listei – presupune legarea noului element înaintea lui prim.

a) Parcurgerea de la stânga la dreapta: procedure parcurg_st. end.(p^. p:=p^. while p<>nil do begin writeln(p^.next end.Stergerea fizica a elementului se realizeaza cu dispose(p). end end. iar elementul urmator lui p^. 4. .pred) .info).3.info). begin p:=prim. b) Parcurgerea de la dreapta la stânga: procedure parcurg_dr.va avea ca urmator element elementul urmator lui p^.Stergerea logica a elementului se realizeaza prin redirectionarea legaturilor astfel încât elementul precedent lui p^ . Lista dublu înlantuita este o lista simetrica. Procedura corespunzatoare va fi urmatoarea: 36 . while p<>nil do begin writeln(p^. p:=p^.Parcurgerea unei liste dublu înlantuita-se poate realiza în ambele sensuri. begin p:=ultim.next). Stergerea unui element : ♦ stergerea elementului oarecare p^ -presupune: . având adresele de legatura atât spre stânga cât si spre dreapta.va avea ca element precedent elementul anterior lui p^.pred.( p^.

p^. procedure sterg_ultim. p:=prim.next:=p^.info<>text do p:=p^.next.next^. dispose(p).pred^. § noul prim element va avea adresa elementului precedent = NIL.pred. begin p:= ultim. si pastrând adresa acestuia în q . p^. dispose(p).când p=ultim (stergerea ultimului element). prim^. ♦ stergerea elementului anterior lui p^ . procedure sterg_prim.procedure sterg.când p=prim (stergerea primului element) presupune parcurgerea urmatorilor pasi: § se salveaza adresa elementului ce va fi sters : p:=prim. while p^.notând cu q^ elementul anterior lui p^. 37 . end. a carui adresa se cunoaste. § se sterge fizic primul element a carui adresa a fost retinuta în p : dispose(p).pred:=p^. ♦ -stergerea elementului p^ . end.pred.next:=nil.next.pred:=nil. stergerea elementului anterior lui p^ se face prin stergerea lui q^. begin write('inf ce va fi stearsa: '). dispose(p) end.next. ultim:=ultim^.next.readln(text). ♦ stergerea elementului p^ . begin p:=prim. prim:=prim^. § variabila prim va lua ca valoare adresa urmatorului element deoarece prin stergerea primului element cel de-al doilea va deveni prim element: prim:=prim^. ultim^.

acesta fiind câstigatorul jocului. 38 . Algoritmul care rezolva aceasta problema este prezentat în partea de aplicatii. Lista poate fi simplu sau dublu înlantuita. adica lista la care se leaga dupa ultimul element chiar primul element al listei. putând fi parcursa în ambele sensuri. Un astfel de exemplu este asezarea unor copii în cerc si numararea lor prin eliminare pâna la ramânerea unui singur copil . Un astfel de exemplu este “ Jocul lui Joseph” . dupa cum este lista initiala.având nevoie de un singur pointer pentru accesarea unui element al listei . Reprezentarea grafica a unei liste circulare simplu înlantuite : prim INF INF ultim … INF La listele circulare procedurile vor fi asemanatoare cu cele de la listele din care sunt create aceste liste. Dupa legarea elementelor listei nu mai stim care este primul si ultimul element al listei .LISTA CIRCULARA Lista circulara este o lista cu proprietatea ca elementul urmator ultimului element este primul element al listei. tinând cont de faptul ca ultimului element al listei îi urmeaza primul ei element. Se pot da exemple de astfel de liste pentru o mai buna întelegere a acestei structuri. Astfel o lista circulara dublu înlantuita va fi si ea simetrica.

plecând dintr-un punct de pe uscat sa se poata trece pe toate podurile. îl împarte astfel C c a d A b e D f g B Portiunile de uscat A. f. Euler a rezolvat aceasta problema introducând un obiect matematic pe care l-a numit graf si care are urmatoarea forma: C c d A g e b a C D f Teoria grafurilor are numeroase aplicatii în fizica. Prima lucrare care abordeaza notiunea de graf dateaza din 1736 si se datoreaza matematicianului elvetian Leonard Euler care a folosit un graf pentru a solutiona problema podurilor din Koenigsberg. c. Râul Pregat. chimie. C. g. Problema consta în a determina daca este posibil ca . sociologie etc. d. D sunt unite între ele prin sapte poduri: a.CAP . II GRAFURI NEORIENTATE 1. Aplicatii specifice grafurilor neorientate sunt cele în care se cere : -sa se determine lungimea minima a lanturilor dintre x si y -sa se determine un lant de lungime minima de la x la y -sa se afiseze(daca exista) un ciclu eulerian al unui graf neorientat G cu n vârfuri si m muchii 39 . inginerie.GENERALITATI Grafurile se studiaza în clasa a X-a la obiectele: “ Bazele informaticii” si la “Aplicatii practice de laborator”. B. e. economie. b. în final revenindu-se în punctul initial. care trece prin acest oras.

4} B={2. iar V contine toate muchiile din U care au ambele extremitati în Y. X fiind o multime finita si nevida de elemente numite noduri sau vârfuri. Multimile A si B formeaza o partitie a lui X. spunem ca u si x sunt incidente. Un graf partial al unui graf dat se obtine pastrând aceleasi vârfuri si eliminând o parte din muchii. fie o submultime a acesteia. Se spune ca un graf partial este indus de multimea V de muchii. numite muchii. Definitie Un subgraf al unui graf G= (X. iar U o multime de perechi neordonate din X. Y_X.î.V) a.6.U) se numeste graf bipartit daca exista doua multimi nevide A si B a. Un subgraf se obtine eliminând o parte din vârfuri si toate muchiile incidente cu acestea. Definitie Se numeste graf neorientat o pereche ordonata de multimi ( X. adicaG1 are aceeasi multime de vârfuri ca G. fie chiar U. Propozitie Un graf complet Kn are Primele 5 grafuri complete sunt: n ( n − 1) muchii. Definitie Se numeste graf complet cu n vârfuri un graf care are proprietatea ca orice doua noduri diferite sunt adiacente. 1 3 4 2 5 6 7 40 A={1.3. Graful se noteaza cu G= ( X . U ) Daca x si y sunt extremitatile muchiei u. U ). la fel ca si u si y . iar multimea de muchii V este .5.U) este un graf H=(Y. X=A 4 B .î. iar vârfurile x si y sunt adiacente în G.7} . U ) a. VU. A 3 B=Ô si orice muchie u a lui G are o extremitate în A si cealalalta în B.-problema existentei într-un graf oarecare a unui ciclu hamiltonian etc. Deci doua muchii care au o extremitate comuna sunt incidente. Vom spune ca subgraful H este indus sau generat de multimea de vârfuri Y.î. 2 o K1 K2 K3 K4 K5 Definitie Un graf G=(X. U ) este un graf G1= ( X . Definitie Un graf partial al grafului G= ( X .

Definitie Un graf bipartit se numeste complet daca pentru orice x din A si orice y din B exista în G muchia [x,y]. 1 4 5 2 6 3 7 A={1,2,3} B={4,5,6,7}

Daca A are p elemente , iar B are q elemente, numarul total de muchii ale unui graf bipartit complet este p*q , iar graful se noteaza Kp,q . Definitie Se numeste graf regulat graful în care toate vârfurile au grade egale. Definitie Un graf K-regulat este un graf regulat în care gradul comun al vârfurilor este K. Exemple: tetraedrul, cubul,octoedrul etc.

Definitie Se numeste lant în graful G, succesiunea de vârfuri L=[x1,x2, …xk] cu proprietatea ca orice doua vârfuri consecutive din L sunt adiacente, adica [x 1,x2 ], [x2,x3],….,[ x k-1,xk] ∈ U. V â r fur il e x 1 si xk se numesc extremitatile lantului , iar numarul de muchii ce apar în L se numeste lungimea lantului. Definitie Daca vârfurile x1,x2, …xk sunt diferite doua câte doua, atunci lantul L se numeste lant elementar. În caz contrar lantul este neelementar. Un lant L poate fi interpretat ca traseul unei deplasari de la x 1 la xk pe muchiile lantului. Definitie Se numeste ciclu în G un lant L pentru care x1=xk , si toate muchiile sunt diferite doua câte doua. Definitie Se numeste ciclu elementar un ciclu care are proprietatea ca oricare doua vârfuri ale sale , cu exceptia primului si a ultimului, sunt diferite doua câte doua.
41

2. REPREZENTAREA GRAFURILOR NEORIENTATE

Exista mai multe modalitati de a reprezenta graful G=(X,U). Aceste reprezentari vor fi utilizate în prelucrarea grafurilor cu ajutorul programelor care implementeaza pe calculator algoritmii respectivi. v Se precizeaza numarul de vârfuri (n) si matricea de adiacenta A a grafului, care este o matrice patratica de ordinul n , cu elementele: 1, daca [i,j] ∈ U A[i,j ]= 0, î n caz contr ar Aceas ta m atr ice es te o m atr ice s im etr ica. D e exem pl u, pentr u gr aful ur m ator v om av ea:
1

A=
2

0 1 0 1 0 1 0 1 0

3

v Se precizeaza nr n de vârfuri si, pentru fiecare vârf i, lista Li a vecinilor sai, adica lista vârfurilor j pentru care [ i,j] ∈ U. Vâ r fi 1 2 3 Lis ta Li a v ecinil or s ai 2 1,3 2

Acest mod de reprezentare poate utiliza si alocarea dinamica a memoriei, precum si un tablou bidimensional T cu doua linii si n+2*m coloane, unde m este nr. de muchii, iar n numarul de vârfuri ale lui G.

42

T [1, i ]=i,

i=1,n

T [2, i ] reprezinta indicele coloanei din T în care este dat primul element din lista Li a vecinilor lui i ; daca I este vârf izolat, atunci T[2, i]=0; daca T[2, i ]=j, atunci T[1,j] este primul dintre vecinii lui i, iar T[2, j] este coloana în T în care apare urmatorul element din lista Li. Daca u este indicele lui T în care apare ultimul element w din Li, atunci T[1,u]=w si T[2,u]=0. Pentru graful de mai sus vom avea: i T[1,i] T[2,i] 1 2 3 4 5 6 7 1 2 3 2 1 3 2 4 5 7 0 6 0 0

v Se dau numarul n de vârfuri, numarul m de muchii, precum si doua tablouri unidimensionale e1 si e2 cu câte m componente fiecare, continând extremitatile muchiilor grafului, adica U={ [e1[1], e2[1] ] , [e1[2], e2[2]],….,[e1[m],e2[m]]}. v O varianta de implementare mai naturala ar fi aceea de a defini un tip de data ‘muchie’ utilizând tipul înregistrare, care sa contina cele doua extremitati ale unei muchii, si apoi de a defini un tablou cu n componente de acest tip: Type muchie=record x,y:byte; end; …………………………… var u:array[1..n] of muchie;

Referirea la extremitatile muchiei se face prin : u[i] .x, respectiv u[i] .y. Acest mod de reprezentare permite înglobarea natulara în tipul de date muchie si a altor informatii asociate muchiilor( cost, lungime ) si este utilizata în problemele în care muchiile se prelucreaza succesiv, eventual dupa o modificare a ordinii lor în tabloul u.

43

neluate înca. fie acesta vârful 1. Repetam pasul 2 atâta timp cât mai exista muchii care nu au fost înca incluse în ciclul C. Plecam dintr-un vârf oarecare. Construim un prim ciclu C parcurgând vârfuri accesibile din aproape în aproape pe muchii din graf. un vârf al ciclului C pentru care mai exista muchii incidente cu el. Construim astfel un nou ciclu C1 pe care îl concatenam cu ciclul C. Ex. Alegem pentru continuare( daca aceasta mai este posibila) . micsorând corespunzator gradele vârfurilor parcurse. GRAFURI EULERIENE Definitie Se numeste ciclu eulerian într-un graf G. Pas 2. Nu ne propunem sa demonstram aceasta teorema. Ne intereseaza algoritmul cu ajutorul caruia putem construi un ciclu eulerian într-un graf despre care stim ca este eulerian.: 3 8 2 6 1 7 4 5 Graf eulerian Teorema de mai sus da o conditie necesara si suficienta ca un graf care nu contine vârfuri izolate sa fie eulerian. Teorema : Un graf G fara vârfuri izolate este eulerian daca si numai daca este conex si gradele tuturor vârfurilor sunt numere pare. 9 44 .3. un ciclu care contine toate muchiile grafului. Definitie Se numeste lant eulerian un lant care contine toate muchiile grafului. obtinând un ciclu mai lung. pentru aceasta se vor parcurge urmatorii pasi: Pas 1. Definitie Se numeste graf eulerian un graf care contine un ciclu eulerian. fiecare muchie fiind prezenta o singura data.

În partea de aplicatii se va prezenta algoritmul care determina toate ciclurile hamiltoniene existente într-un graf (care se dovedeste a fi hamiltonian).U) este un graf cu n>=3 vârfuri.n}. GRAFURI HAMILTONIENE Definitie Se numeste ciclu hamiltonian un ciclu elementar care contine toate vârfurile grafului G. i!j [x[1]. x[2]] . astfel încât gradul fiecarui vârf x χX satisface conditia: d(x)ƒ atunci G este hamiltonian. Conditiile interne ce trebuiesc satisfacute sunt urmatoarele: x[i] ! x[j] … (i. Acest algoritm .[x[n-1].…. Ciclurile se genereaza utilizând un vector x cu n componente. x[n]] χ U si [x[n]. x[1]] χ U n 2 45 . [x[2]. foloseste metoda backtracking.j)χ{1. Definitie hamiltonian. x[3]] .2..4. 1 5 2 3 4 Graf hamiltonian 4 Ciclu hamiltonian 5 3 1 2 Teorema : Graful complet Kn este hamiltonian Teorema: Daca G=(X. Se numeste graf hamiltonian un graf care contine un ciclu Definitie Se numeste lant hamiltonian un lant elementar care contine toate vârfurile grafului.….

{variabila sol numara ciclurile hamiltoniene} x[1]:=1.k-1 executa {vârfurile trebuie sa fie diferite} daca x[i]=x[k] atunci v:=0. dupa care se întoarce în orasul din care a plecat. Pas 1 : sol:=9.Pentru a nu produce de mai multe ori acelasi ciclu. 46 . {se merge la urmatoarea componenta. diferind ordinea de parcurgere a nodurilor.1]=1) atunci sol:=sol+1 scrie ciclul ham. v:=1. daca a[x[k-1]. problema cere sa se determine un ciclu hamiltonian de cost minim în graful Kn ale carui vârfuri sunt cele n orase. x[k]]=0 atunci v:=0. x[2]:=1. vom fixa x[1]=1. Cu alte cuvinte. se cere sa se determine un traseu care sa viziteze o singura data cele n orase si care sa aiba costul total minim. sa verificam daca el a mai fost generat o data. din care se va deduce prima valoare posibila} O problema înrudita cu cea a gasirii într-un graf a unui ciclu hamiltonian este problema voiajorului comercial: Un voiajor comercial trebuie sprezinte în n orase produsele fabricii pe care o reprezinta.Putem evita acest lucru memorând ciclurile generate si . {se fixeaza primul vârf al ciclului} k:=2. . de fiecare data când terminam generarea unuia. Rezolvarea acestei probleme va fi prezentata în partea de aplicatii. Oricum fiecare ciclu hamiltonian este generat de doua ori. atâta timp cât ( x[k]+1 [n ) and ( v=0 ) executa x[k]:=x[k]+1. Cunoscându-se costul deplasarii între oricare doua dintre cele n orase. {se pune în x[2] valoarea 1 din care se va deduce prima valoare posibila a acestei componente} Pas 2 : atâta timp cât k>1 executa v:=0. x[k]:=1. care se initializeaza cu valoarea 1. {se porneste de la ideea ca pozitionarea facuta este buna si se modifica v în caz contrar} pentru i:=1. {se testeaza existenta muchiei între x[k-1] si x[k]} daca v=0 atunci k:=k-1 {se face un pas înapoi } altfel daca (k=n) and (a[x[n]. iar costul unui ciclu reprezinta suma costurilor muchiilor sale. obtinut altfel daca k<n atunci k:=k+1.

trecânduse la primul dintre vecinii sai. în cazul în care se începe cu nodul 1 si alegerea nodurilor se face în ordine crescatoare. daca nu. Se parcurge linia j din A începând cu urmatorul element. Notam cu ps pointerul de stiva. nevizitati înca. pentru graful de mai jos. De exemplu.8 . În continuare se procedeaza similar cu vârful j. poate fi aplicata atât în cazul grafurilor neorientate cât si în cel al grafurilor orientate. este plasat în vârful stivei .3. 47 . sa fie atins o singura data.5. fie acesta j .6.7. încercând sa continuam cu urmatorul element din stiva. pâna este gasit un vecin al lui j nevizitat înca. Metode de parcurgere a grafurilor neorientate : v metoda de parcurgere DF ( Dept First ) sau parcurgerea în adâncime.î. plecând dintr-un vârf dat i a. Daca el este gasit. acesta din urma fiind plasat în vârful stivei. PARCURGEREA GRAFURILOR NEORIENTATE Prin parcurgerea unui graf neorientat se întelege examinarea în mod sistematic a nodurilor sale. parcurgerea DF este :1.4. În vectorul urm vom determina în fiecare moment urmatorul nod ce va fi vizitat dupa nodul j (atunci când acesta exista). Parcurgerea începe cu un vârf initial dat i si continua cu primul dintre vecinii sai nevizitati . fiecare nod accesibil din i pe muchii adiacente doua câte doua. 1 2 3 4 5 6 7 8 Pentru implementarea algoritmului se utilizeaza vectorul viz si o stiva S care ne permite sa plecam în fiecare moment de la vârful curent spre primul dintre vecinii sai nevizitati.2.5. marind si ps . ps se micsoreaza cu 1.

în caz contrar 48 . 1. { scoate nodul din stiva} determina primul dintre vecinii k ai lui j. 8.3. {toate vârfurile sunt nevizitate} urm[j]:=0.2.n}. parcurgerea BF corespunzatoare va fi: 1.4.d.5.m. {plasam în vârful stivei S vârful i } {pointerul de stiva ps pointeaza spre vârful stivei } Pas 3. { vârful k este vizitat} viz[k]:=1. ps:=1. vom determina prima valoare posibila pentru primul nod spre care se poate pleca din vârful j} sfârsit pentru Pas 2. apoi a vecinilor nevizitati ai acestora s. S[1]:=i. stop Programul Pascal care implementeaza algoritmul va fi prezentat în partea de aplicatii. memora pe k în S} Pas 4 .….Algoritmul în pseudocod este urmatorul: Pas 1.n executa viz[j]:=0. dintre toti vecinii unui vârf . {pune k în urm[j]} daca nu exista un astfel de k atunci ps:=ps-1 {se coboara în stiva} altfel scrie k. Atâta timp cât ps=1 executa {stiva este nevida} j:=S[ps]. Pentru graful de mai sus . pe acela nevizitat înca si care îndeplineste conditia impusa. {pornind din 0. Pentru constructia practica a algoritmului. daca vârful j a fost vizitat viz[j]= 0.2. în vederea alegerii la un moment dat. v metoda de parcurgere BF ( Breath-First) – sau parcurgerea în latime. astfel: …jχ {1. Pentru j:=1. apoi a vecinilor acestuia.a.7. vom folosi un vector viz cu n componente.6. nevizitati înca urm[j]:=k.{se mareste ps pentru a-l S[ps]:=k. Parcurgerea în latime presupune vizitarea întâi a vârfului initial i.

Aceasta se deosebeste de parcurgerea BF prin faptul ca prelucreaza mereuultimul nod la care s-a ajuns.8.=i. nevizitati înca. {adauga vârful j în coada C} Viziteaza vârful j. {scoate vârful urmator din coada} Pas 3. {cu p pointam la primul element al cozii iar cu u la ultimul} viz[i]:=1. v Metoda de parcurgere D (depth) –în cazul în care lista folosita este o stiva se obtine parcurgerea depth. Algoritmul în pseudocod este urmatorul: Pas 1. 3.7. Evident.5.{se trece la urmatorul element ce va fi scos din coada C} Pas 4. Pentru exemplul considerat. 49 .4.n executa viz[j]:=0. 1.} p:=1.5. {In coada C memoram initial doar vârful i. V:=C[p]. algoritmii BF si D pot fi folositi pentru parcurgerea unui graf neorientat care nu este conex sau pentru grafuri orientate. C[u]:=j. nevizitate înca. vârful dat. executa u:=u+1. Pentru j:=1. {se viziteaza vârful I} Pas 3. Pentru toti vecinii j ai lui v. {vârful a fost vizitat} Pas 3. Pas 2. parcurgerea D se va face în ordinea : 1. La fel ca si cazul algoritmului DF. Cele mai utilizate metode de parcurgere sunt DF si BF.6. viz[j]:=1.3.2. Initial v este egal cu i. Stop. C[1].u:=1.În vectorul C vom gestiona o coada în care prelucrarea unui vârf v aflat la un capat al cozii consta în introducerea în celalalt capat al ei a tuturor vârfurilor j vecine cu v. p:=p+1. Atâta timp cât p[ u executa {coada este nevida} Pas 3. 2. Programul Pascal de parcurgere a grafurilor neorientate prin metoda BF va fi prezentat în partea de aplicatii.

Prezentam algoritmul care verifica daca un graf este conex. În cazul în care graful nu este conex vom cere sa se determine numarul componentelor conexe ale grafului dat. Se initializeaza numarul nc de componente conexe cu 0 (nc:=0_. Pas 3: Se testeaza nc. CONEXITATE Definitie Se numeste graf conex un graf cu proprietatea ca pentru oricare doua vârfuri x si y diferite ale sale exista un lant care le leaga. Daca nu. Algoritmul este urmatorul: Pas 1: Se alege un vârf x (ex> x=1 ). utilizând parcurgerea BF . 2 1 3 4 4 6 7 Graf conex 3 5 Graf neconex 8 5 8 1 2 6 7 Definitie Se numeste componenta conexa a grafului G=(X. un subgraf C=(X1. Daca nc este 1. o lista a vârfurilor care. Se stie ca în urma parcurgerii BF a unui graf obtinem . reprezinta multimea tuturor vârfurilor care sunt legate prin lanturi de un vârf dat. Acest algoritm se bazeaza pe parcurgerea BF.U). luând x ca vârf de plecare. Pas 2: Se mareste nc cu 1 (nc:=nc+1 ). se concluzioneaza ca graful este conex. CAP . Aceasta reprezinta multimea de vârfuri ale componentei conexe nc . de fapt. se alege un vârf x înca nevizitat si se reia pasul 2. Se determina si se afiseaza multimea vârfurilor legate de x prin lanturi.6. III 50 . U1) conex al lui G care sa lege un vârf din X1 cu un vârf din X-X1. Daca nu. se precizeaza numarul total de componente conexe. Daca toate vârfurile au fost vizitate. se trece la pasul 3.

ARBORI 1. De studiul lor s-au ocupat matematicieni si fizicieni de seama: Cayley a studiat arborii pentru aplicatiile lor în chimia organica.2. arborii reprezinta grafurile cele mai simple ca structura si cele mai frecvent utilizate în practica. iar Kirchhoff a studiat aceasta categorie de grafuri pornind de la studiul retelelor electrice. Ex. exemplu care îi va ajuta pe elevi sa înteleaga mai usor acest tip de structura de date. Directoarele sistemului de operare sunt structurate sub forma unui arbore Hard Disc Software Comm Draw Write Programs Docs General Teaching Research Utils 3. care au aceeasi formula chimica C4 H 10 pot fi reprezentate astfel: H H H H H H C C C C H H H H H H H H C C C H H C H H H H Ex. Termenul de arbore a fost introdus de Cayley în 1857. plecând de la o analogie botanica. elementele sunt structurate pe niveluri astfel: 51 . Doua hidrocarburi saturate : butanul si izobutanul . GENERALITATI: În clasa grafurilor conexe. Arborele genealogic al unei persoane este un alt exemplu de structura arborescenta. 1. Într-o stuctura de tip arbore.

Nodurile care nu au descendenti se numesc frunze . se numeste element terminal sau frunza. Corolar: Un graf G=(X.. la rândul lor pot avea fii. . acestea numindu-se fiii elementului considerat..Un graf conex este un graf în care pentru oricare doua vârfuri exista un lant care le leaga.. Fiecare nod are un singur tata . Se vor reaminti elevilor notiunile de graf conex si de ciclu: . nivelul 3 Definitie : Se defineste un arbore ca fiind un graf conex si fara cicluri. În cazul în care un element nu mai are nici un fiu. radacina arborelui ……………………………. nivelul 2 ……………………. nivelul 1 ………. Definitie Se numeste arbore partial un graf partial H al grafului G care în plus este si arbore. elemente care se vor numi fii si care formeaza nivelul 1.U) contine un arbore partial daca si numai daca G este conex.pe primul nivel (nivel 0 ) exista un element unic numit radacina . de care sunt legate elementele de pe nivelul urmator (nivelul 1 ). .pe celelalte niveluri se gasesc elemente legate de elementele de pe nivelurile anterioare si care . Facându-se analogia cu arborele genealogic se vor defini notiunile cu care se vehiculeaza în prelucrarea arborilor : Fiecare element se numeste tata pentru elementele de pe nivelul urmator care sunt legate de el.pe urmatorul nivel se gasesc elementele legate de radacina.Un ciclu în G este un lant pentru care ultimul element al lantului este chiar primul element al lui si toate muchiile sunt diferite doua câte doua. Nodurile care au acelasi tata se numesc frati. nivelul 0 ………………. . cu exceptia radacinii care nu are tata. 52 .

iar. 53 . de alimentarii cu apa.Sortarea elementelor unui sir prin selectie arborescenta (arbori de sortare). O problema concreta în care intervine problema determinarii arborelui partial de cost minim este cea a conectarii oraselor cu cost minim. de comunicatii. suma muchiilor este minima.Propozitia 1.U) care nu contine cicluri se numeste graf aciclic. sunt cunoscute mai multe metode. Definitie Un graf G=(X. costuri. Definitie Un graf G care nu contine cicluri se numeste padure. Se poate cere astfel : sa se determine un arbore partial de cost minim. sa se determine toti arborii partiali minimi sau sa se determine numai aceia care satisfac diverse restrictii de optimizare. Astfel ei sunt utilizati pentru: .Memorarea si regasirea rapida a unor informatii (arborele binar de cautare) . Propozitia 2.Notatia poloneza a expresiilor aritmetice. . Vor fi prezentati cei doi algoritmi de determinare a unui APM cunoscuti ca: Ø Algoritmul lui Kruskal Ø Algoritmul lui Prim Un mare numar de aplicatii utilizeaza în rezolvarea lor arborii binari . . APLICATII : În diverse aplicatii (proiectarea unor retele de transport. Orice arbore H=(X. Orice arbore cu n vârfuri are n-1 muchii.Reprezentarea functiilor compuse cu ajutorul arborilor binari. Arborele partial de cost minim este arborele partial la care între oricare doua noduri exista un drum.Arborii binari perfect echilibrati etc. preturi . în plus. Pentru determinarea unui APM al unui graf conex . de energie electrica etc. . .Reprezentarea arborelui genealogic (arbore oarecare) cu ajutorul unui arbore binar.V) cu n ƒ 2 vârfuri contine cel putin doua vârfuri terminale.) apare frecvent problema determinarii arborilor partiali de cost minim care sa satisfaca restrictii de conexitate si sa minimizeze (maximizeze) anumite lungimi.

în plus .2. X = {1. care asociaza fiecarei muchii u. respectiv un arbore: Teorema (caracterizarea unei paduri). numit costul sau. exista un unic lant care le uneste. ARBORE PARTIAL DE COST MINIM Fie un graf G = ( X. Definitie pentru un graf partial H = (X. egalitatea având loc când graful este un arbore. Un arbore partial conex reprezinta modalitatea ortima din punct de vedere financiar de a lega direct unele perechi de orase a. 54 . Aceasta problema este cunoscuta si sub numele de “problema conectarii cu cost minim a oraselor”. în final orice doua orase sa fie conectate (direct sau prin intermediul altora).î. Teorema (caracterizarea unui arbore). Propozitie: Pentru graful G conex. exista un graf partial H conex si de cost minim. Presupunem cunoscute teoremele care caracterizeaza o padure. V) al lui G. iar costul muchiei [i .2. este arbore. adica: c(H) = u∈V ∑ c (u ) Pentru un arbore partial de cost minim folosim notatia prescurtata APM. cu functia de cost c. 2) Pentru oricare doua noduri distincte. Problema : Sa se determine un graf partial H al lui G care sa fie conex si sa aiba costul minim. Fie graful G cu n noduri.…. Graful G este o padure daca si numai daca pentru oricare doua noduri ale lui G exista cel mult un lant care le uneste. Teorema Orice graf conex contine cel putin un arbore partial. deoarece putem sa interpretam cele n vârfuri ale grafului ca fiind orase. 6) G este minimal în raport cu proprietatea de conexitate.U ) conex. Urmatoarele conditii sunt echivalente: 1) G este un arbore. 3) G este aciclic si are n-1 muchii. 4) G este conex si are n-1 muchii. Propozitie Pentru orice graf conex de tip (n.m) exista relatia mƒ n-1. 5) G este maximal în raport cu proprietatea de aciclitate.3. un numar real pozitiv c(u). si o functie c : UτR. care. j ] ca reprezentând costul conectarii directe a oraselor i si j.n}. costul sau reprezinta suma costurilor muchiilor sale.

y i .m ) * se ordoneaza muchiile xi . pentru j:=1.n { se initializeaza marcajele vârfurilor} i ρ 0. ALGORITMUL LUI KRUSKAL Având la baza metoda Greedy pentru rezolvarea unei probleme de optimizare. i:=1.( xi .m executa daca L xj !Ly j {extremitatile muchiei j sunt în componente conexe diferite} atunci iρi+1 Si ρj { se adauga muchia j în arbore } cost ρ cost + cj marcaj1 ρ L xj { se unifica componentele conexe} marcaj2 ρ Ly j pentru k=1. y i crescator dupa costurile c i Li ρ i . . c i . costρ0. algoritmul construieste un arbore partial optim astfel: .la fiecare pas se alege acea muchie de cost minim din cele neselectate anterior si care nu formeaza ciclu cu cele selectate deja. Algoritmul lui Kruskal prezentat în pseudocod: citeste n. 55 . .1.construirea arborelui partial optim al unui graf conex cu n noduri se sfârseste atunci când arborele construit are n-1 muchii. Programul Pascal va fi prezentat în partea de aplicatii. i:= 1.2.n executa daca Lk=marcaj2 atunci Lkρmarcaj1 daca i=n-1 atunci scrie solutia S si costul c *oprire fortata scrie ‘ Graful initial este neconex ‘ stop.m .initial se pleaca de la graful partial vid.

vectorul costurilor} naρ0 {contorizeaza nr APM obtinuti} for i:= 1.2. algoritmul lui Prim construieste un arbore partial optim minim pornind cu o multime formata dintr-un singur nod si o multime de muchii.Si acest algoritm se încadreaza în metoda Greedy. na ρ na +1. i2 ρ E ( j.2. Arborele se construieste treptat prin adaugarea la fiecare pas a muchiei cu cel mai mic cost care formeaza cu precedentele muchii alese un arbore. 3. i2 sunt extremitatile muchiei } nod ρ nod 4 { i1 . i2 ρ E{ j .m. C. {nod-vector ce memoreaza nodurile } cost ρ 0.C {E. 2 ) until ( i1 = i ) or ( i2 = i ) { i1. ALGORITMUL LUI PRIM În timp ce algoritmul lui Kruskal consruieste un APM prin construirea multimii muchiilor arborelui minimal . ARBORI BINARI 56 . 2 ) until ( i1 χ nod ) xor ( i2 χ nod ) nod ρ nod 4 { i1.n-1 jρ0 repeat j ρj+1 i1 ρ E ( j.matricea muchiilor. arb ( na )ρj { alegerea celorlalte n-2 muchii} for k=2. i2 } arb(na)ρ arb(na) 4 { j } { se testeaza daca s-a obtinut un arbore nou} j ρ0 repeat jρj+1 until arb(j) = arb(na) if j < na then na ρ na-1 stop .n {se genereaza arborele pornind de la nodul i} nod ρ Ô . i2 } cost ρ cost + C( j ). vida. 1 ). Algoritmul lui Prim în pseudocod este: Program Prim Citeste n. E. adaugându-i la fiecare pas muchia cu cel mai mic cost care nu formeaza cicluri cu muchiile aflate în matricea muchiilor arborelui minimal . j ρ 0 { se determina muchia de cost minim ce pleaca din i } repeat j ρ j+1 i1 ρ E( j . 1 ).

: Se va face distinctie între fiul stâng si fiul drept al arborelui Definitie Un arbore binar complet este un arbore în care fiecare nod . Deci arborele binar este o structura recursiva de date.Definitie: Un arbore binar este un arbore în care fiecare nod are cel mult doi fii: fiul stâng si fiul drept. care nu este terminal. Daca se elimina radacina si legaturile ei se obtin doi arbori binari care se numesc subarborii stâng si drept ai arborelui initial. Un arbore binar nevid fie se reduce la radacina . Ex. are doi fii. 57 . fie cuprinde radacina si cel mult doi subarbori binari.

Acest lucru se poate reprezenta grafic astfel: 1 2 NIL NIL 3 NIL 4 5 NIL 6 NIL NIL 7 NIL NIL 8 NIL Declararea unei structuri de tip arbore se face astfel: Type reper=^arbore. acestea exprimând legaturile existente între arbori. adresa fiului stâng si adresa fiului drept.1. arbore= record inf : byte. iar D[i] descendentul drept.dr: reper end. Se specifica radacina si pentru fiecare vârf se specifica descendentul stâng si cel drept. Ø O alta reprezentare se realizeaza cu ajutorul vectorilor. pe lânga informatia propriu-zisa asociata nodului. 58 . S[i]=0 sau D[i]=0 semnifica lipsa unui descendent stâng. INF [i] reprezinta informatia asociata nodului. unde . S[i] specifica descendentul stâng. pentru fiecare vârf i. var radacina : reper. Se folosesc doi vectori S si D. st.3. respectiv a unui descendent drept. fiecare element cuprinzând . REPREZENTAREA ARBORILOR BINARI Ø Un arbore binar se poate implementa foarte usor cu ajutorul adreselor de înlantuire.

: Fie arborele: 1 n=7 2 3 5 RAD = 1 S=( 2. 1. -1.0 ) D=( 3. 0. Pentru arborele de mai sus vom avea: TATA = ( 0. Ei trebuie sa stie ca alocarea statica a arborilor este posibila atunci când în problema se cunoaste numarul maxim de noduri ale arborelui. 3.Ex. 5. 59 . -1. 0. pentru fiecare vârf i nodul TATA [ i ] si Desc care indica prin valoarea –1 sau 1 daca vârful i este descendentul stâng sau drept al parintelui sau TATA[i]. 5. 0 . 3.6 . 7. 1 ) Elevii trebuie sa stie sa aleaga acel mod de reprezentare care îi avantajeaza în rezolvarea fiecarei probleme în parte. 5 ) DESC = ( 0. -1.4 . 0. 1. 0 ) 7 4 6 Ø O alta reprezentare a arborilor binari se realizeaza dându-se vectorii TATA care precizeaza. 1. 1.0 .0 .

3.val. descompunând problema în trei subprobleme: 1.':'). nod=record inf:byte. si-l leaga de rad} end else p:=nil. Daca cele trei probleme de dimensiuni mici sunt rezolvate. nodului '.p^. presupune alocarea memoriei si initializarea zonei de informatii asociate nodului. utilizeaza o functie de creare numita arbore care returneaza adresa radacinii arborelui creat: Program creare_parcurgere_arbore_binar . CREAREA SI TRAVERSAREA UNUI ARBORE BINAR Crearea unui arbore binar se rezolva prin metoda divide et impera . prezentat în continuare.2. st.val.{gen. subarb.dr:=arbore. dr. Rezolvarea unei probleme de dimensiune 1 (crearea unui nod radacina). {adresa radacinii arborelui} function arbore:reper. si-l leaga de rad} write('nodul din dr. crearea subarborelui drept. 3. type reper=^nod. 60 . subarb. crearea nodului radacina (dim=1). În acest fel s-a construit un subarbore mai mare care reprezinta solutia unei subprobleme din descompunere. st. 2. if val>0 then {subarborele este nevid} begin new(p). arbore:=p.st:=arbore.inf:=val. val:byte. begin read(val). Prin combinarea solutiilor se continua constructia arborelui. var rad:reper. {returneaza adresa radacinii} var p:reper. nodului '. end. crearea subarborelui stâng. Programul care creaza un arbore binar .{generarea radacinii p^ a subarborelui} write('nodul din stg.':'). p^. p^. în faza de combinare a solutiilor se leaga nodul radacina de cei doi subarbori. Problema crearii unui subarbore vid se rezolva prin initializarea variabilei reper asociata radacinii arborelui cu constanta NIL . Descompunerea continua pâna se ajunge la problema crearii unui subarbore vid (dim=0) .{gen.dr:reper end.

3. 3. Exista trei modalitati importante de traversare a arborelui: a) Traversarea în preordine : se viziteaza radacina. 1.Astfel. b) Traversarea în inordine : se viziteaza în inordine nodurile subarborelui stâng. operatie echivalenta cu o liniarizare a arborelui. Parcurgerea arborilor este o problema care se poate descompune în trei subprobleme identice. putem scrie urmatoarele proceduri: procedure preordine(p:reper). nodurile subarborelui drept. nodurile subarborelui drept . tot în postordine . 4 postordine: 2. 2. 7.st). c) Traversarea în postordine : se viziteaza în postordine nodurile subarborelui stâng. si apoi . 5. 7. c) Parcurgerea subarborelui drept. 5. 7. 4 inordine: 2. 6. fiecare nod sa fie atins o singura data. 5. 1 6 7 Considerând declaratiile arborelui creat mai sus . 61 .Parcurgerea arborilor binari consta în examinarea în mod sistematic a nodurilor sale a. pentru parcurgerea în preordine . begin if p=nil then begin write(p^. si apoi radacina. 6. 6. apoi . problema se descompune în urmatoarele subprobleme de dimensiuni mai mici: a) Parcurgerea radacinii ( un singur nod => dimensiunea=1) b) Parcurgerea subarborelui stâng. apoi .inf:2). 3. {S} preordine(p^. se viziteaza nodurile subarborelui stâng .î. tot în preordine. {R} preordine(p^. Descompunerea subproblemelor b) si c) continua pâna când se ajunge la subarbori vizi. tot în inordine . Traversarea arborelui presupune vizitarea fiecarui nod o singura data. 4. apoi acelea ale subarborelui drept. Fie arborele: 1 2 3 Parcurgerea acestuia furnizeaza vârfurile în ordinea urmatoare: 4 5 preordine: 1. apoi radacina.dr). {D} end end.

{S} {D} {R} Programul principal care apeleaza procedurile respective va fi: begin writeln('nodul radacina:').st). writeln. postordine(p^. inordine(rad).readln end. write(p^.writeln('arborele parcurs in inordine: '). writeln. rad:=arbore. {S} write(p^.dr).dr). preordine(rad). {D} end end.inf:2).st). end end. begin if p=nil then begin inordine(p^.inf:2).procedure inordine(p:reper).writeln('arborele parcurs in preordine: '). begin if p=nil then begin postordine(p^. {R} inordine(p^. 62 . procedure postordine(p:reper).writeln('arborele parcurs in postordine: '). writeln. postordine(rad). writeln.

read(p^.dr:=nil.st:=arbore(ns) else p^.inf).nd:byte.rad.3. begin write('nodul: '). nd:=n-ns-1. ns.st:=nil. new(p). subarb.{returneaza radacina subarborelui creat } var p:reper.3. {gen.} ns:=n div 2. {gen subarb st cu ns noduri} if ns>0 then p^. APLICATII ALE ARBORILOR BINARI v ARBORE PERFECT ECHILIBRAT Definitie Se numaste arbore perfect echilibrat acel arbore care are diferenta dintre numarul vârfurilor subarborilor oricarui vârf din arbore egala cu cel mult 1.dr:=arbore(nd) else p^. Ex 1 1 2 5 2 6 3 4 6 7 3 4 7 8 n=7 5 n=8 Conditia din definitia arborelui este respectata pentru un arbore cu n vârfuri daca subarborele stâng are [n / 2] vârfuri . arbore:=p end. Subprogramul de generare al unui astfel de arbore este urmatorul: function arbore (n:byte) :reper . {gen subarb dr cu nd noduri} if nd>0 then p^. v ARBORI DE SORTARE 63 . iar subarborele drept are n – [n / 2 ] – 1 vârfuri.

altfel exista doua puteri consecutive ale lui 2.Definitie Se numeste arbore de sortare un arbore binar complet care are toate vârfurile terminale pe un singur nivel sau pe doua nivele consecutive. pentru n=6 putem sa construim urmatorul arbore de sortare: 5 1 2 3 4 4 6 64 . fie ele 2r si 2r+1 a. atunci arborele de sortare corespunzator are toate vârfurile terminale pe acelasi nivel. avem urmatoarea relatie: x+y=n Pe de alta parte. Arborii de sortare sunt folositi în sortarea elementelor unui sir printr-o metoda numita selectie arborescenta Daca n este o putere a lui 2 . pornind de la arborele de sortare. sa avem: 2r <n< 2r+1 În acest caz arborele de sortare corespunzator are vârfurile pe nivelele consecutive r si r+1. fiecarui vârf de pe nivelul r îi asociem doi descendenti (pe nivelul r+1) am obtine un arbore binar complet cu toate vârfurile terminale pe acelasi nivel (r+1). am avea urmatoarea relatie: x + 2* y=2 r+1 Grupând relatiile de mai sus obtinem un sistem de doua ecuatii cu doua necunoscute. si.î. Notând cu x numarul de vârfuri terminale de pe nivelul r+1 si cu y numarul de vârfuri terminale de pe nivelul r. evident. dupa a carui rezolvare obtinem: x = 2* n . daca . Vârfurile terminale sunt asociate celor n elemente ale unui sir care se doreste a fi ordonat crescator.2r+1 y=n–x De exemplu .

parinte al unuia dintre cele x noduri terminale de pe nivelul r+1 sau un nod terminal. adica în a[1]. Acest lucru îl realizam folosind o procedura recursiva care va construi un nod interior sau un nod terminal. Pentru a implementa în Pascal acest algoritm va trebui sa construim întâi arborele de sortare. în functie de nivelul pe care ne situam. Pentru elementele ramase vom executa urmatorul pas: Fie lantul care uneste radacina cu vârful terminal din care a provenit valoarea minima.Completam de jos în sus vârfurile interioare ale arborelui cu minimul valorilor asociate descendentilor. Va trebui sa calculam întâi valorile lui r . pentru a cunoaste locul în care se va introduce valoarea maxint si de unde va pleca în sus pentru completarea corecta a valorilor nodurilor interioare cu minimul valorilor celor doi descendenti. Extragem din radacina valoarea minima. punând-o pe locul sau definitiv. calculându-se valoarea minima dintre valorile asociate descendentilor sai. Se parcurge apoi lantul spre radacina si se corecteaza valoarea asociata fiecarui vârf. iar daca suntem pe nivelul r. trebuie sa facem distinctie între cazul în care construim un nod interior. În nodul parinte asociat lui z urca valoarea asociata vârfului frate al lui. Metoda de selectie arborescenta este inspirata din organizarea unui turneu prin eliminare . Scoaterea valorilor din arborele de sortare se face cu procedura recursiva cauta. Se memoreaza aceasta valoare în a[2] si se continua astfel pâna la extragerea din arbore a tuturor valorilor sale provenite din sirul initial. Evidenta construirii nodurilor terminale o tinem cu variabila z. 65 .Elementele ce se vor sorta sunt plasate pe varfurile terminale de la stânga la dreapta. x si y . iar a nodurilor neterminale ( în numar de x/2 ) de pe nivelul r cu variabila u. În radacina va ajunge astfel elementul minim din elementele ramase în sir. el determinându-se în urma a n-1 comparatii între elementele sirului. Este important sa stim de unde vine valoarea în radacina. Programul Pascal de sortare folosind selectia arborescenta va fi prezentat în capitolul de aplicatii. care merge în adâncime pâna când se identifica vârful în care urca valoarea asociata descendentului pentru care valoarea fratelui sau este eliminata din arbore în etapa curenta. În vârful radacina al arborelui se va gasi cel mai mic element din sir.

în general. iar nodurile ale caror chei au valori mai mari decât v se gasesc în subarborele sau drept.în stânga ei se pune cuvântul urmator care-l precede alfabetic pe primul .d. daca cuvântul este diferit de cele existente deja. 66 . cautarea presupunând testarea a cel mult atâtea noduri câte niveluri are arborele binar de cautare.m. câte unul de pe o linie. Cautarea unei informatii identificate printr-o valoare v a cheii începe de la radacina si se termina în cel mai rau caz la unul din nodurile terminale.a.în radacina se pune primul cuvânt . . In capitolul cu aplicatii se exemplifica utilizarea arborilor de cautare în rezolvarea unei probleme care se numeste “ Construirea concordantelor “ . Afisarea cuvintelor se obtine în ordine alfabetica daca se traverseaza arborele de cautare în inordine.în dreapta se pune cuvântul urmator care-i urmeaza alfabetic s.v ARBORELE BINAR DE CAUTARE Definitie Se numeste arbore binar de cautare un arbore ale carui noduri cuprind o singura cheie de identificare. Fiecare nod din arbore cuprinde. Aceasta problema cere sa se afiseze cuvintele distincte si frecventa lor de aparitie stiind ca se citesc mai multe cuvinte. traversarea acestuia în inordine parcurge nodurile în ordinea crescatoare a valorilor cheilor asociate. în afara de cuvântul care reprezinta cheia de identificare a nodului si frecventa de aparitie si cele doua adrese de înlantuire. Adaugarea unui cuvânt în arbore presupune cautarea lui în structura arborescenta si legarea lui de nodul terminal corespunzator. nodurile cu chei mai mici decât valoarea cheii asociate unui anumit nod se gasesc în subarborele stâng al acestuia. Dispunerea nodurilor arborelui pe niveluri face ca numarul testelor la cautare sa fie . pâna la CTRL / Z. Cuvintele citite vor fi puse într-un arbore binar de cautare astfel: . mai mic decât în cazul listelor ordonate. Daca cheile asociate unui arbore binar de cautare sunt numerice.

sa se afiseze cel mai apropiat stramos comun al celor doua persoane.: 1 tata 4 1 2 3 frati ===> 2 5 3 6 4 7 ===> 5 6 7 frati 1 2 frati 5 3 frati 6 4 7 Problema a carei rezolvare este prezentata în capitolul cu aplicatii are urmatorul enunt: Se considera un arbore genealogic care cuprinde descendentii unei persoane. Fiind date numele a doua persoane din familie . Ex. iar ceilalti fii . Datele se considera corecte.v ARBORELE GENEALOGIC Arborele genealogic al unei persoane este un arbore oarecare . fratii primului. nodurile neterminale ale arborelui putând avea unul sau mai multi fii. se leaga între ei ( pe legatura dreapta ). 67 . Un arbore oarecare poate fi reprezentat ca un arbore binar daca se pastreza legatura spre tata numai pentru primul fiu ( legatura stânga ).

Forma poloneza prefixata Ç a lui E se obtine astfel: Ø â =a. ca subarbore stâng arborele asociat expresiei E1.Daca expresia aritmetica E este de forma E1 op E2 . Se poate asocia unei expresii aritmetice E un arbore binar complet astfel: .Daca E = (E1). a*b . pentru orice expresie aritmetica 68 . Lukasiewicz.v FORMA POLONEZA A EXPRESIILOR ARITMETICE Este una dintre cele mai importante aplicatii ale arborilor binari si a fost introdusa de matematicianul polonez J. a-b . a/b . a^b arborii binari asociati sunt: + * / ^ a b a b a b a b a b Teorema Parcurgerea în preordine a unui arbore binar asociat unei expresii aritmetice E da forma prefixata a expresiei E. pentru orice expresii aritmetice E1 si E2 Ø ( E )= E . iar E1 si E2 sunt expresii aritmetice. iar ca subarbore drept. Ex. . arborele binar complet asociat are în radacina operatorul op . Definitie Fie o expresie aritmetica .Unei expresii aritmetice formate dintr-un singur operand îi asociem un arbore binar format doar din nodul radacina în care punem operandul respectiv . pentru orice operand a care este o constanta sau o variabila Ø E1 op E2 =op E1 E2. unde E1 este o expresie aritmetica.: Pentru expresiile aritmetice simple : a+b . unde op este unul dintre operatorii admisi . arborele binar asociat expresiei E2. atunci arborele binar asociat lui E coincide cu arborele binar asociat lui E1.

g(y.h(z))) se poate reprezenta prin urmatorul arbore binar: f f j x y y z g h Parcurgerea în preordine a arborelui corespunde scrierii f f j x y g y h z care se realizeaza deci fara paranteze 69 . a*b+c/d-e=-a*b+c/de=-+a*bc/de=-+*ab/cde Obs. v REPREZENTAREA FUNCTIILOR COMPUSE Parcurgerea în preordine a arborilor binari permite scrierea functiilor compuse fara paranteze. formei prefixate va fi prezentat în capitolul care contine aplicatii.y).:Forma poloneza asociata unei expresii aritmetice nu este unica. Atunci functia compusa f(f(j(x). Pentru a întelega acest lucru sa luam urmatorul exemplu: Fie f si g doua functii de doua variabile si h si j doua functii de o variabila.Programul care construieste un arbore binar asociat unei expresii si obt. forma poloneza prefixata asociata este: -+*ab/cde Într-adevar .Pentru expresia E= a*b+c/d-e.

Un subgraf se obtine eliminând o parte din vârfuri si toate arcele incidente cu acestea.î.6) Definitie Un graf partial al grafului G= ( X . Y_X.4). fie chiar U. Vom desena un graf partial al lui si un subgraf al lui: 1 1 2 3 2 3 4 5 6 4 graf partial subgraf Definitie Un subgraf al unui graf G= (X.4).5). iar U o multime de perechi ordonate de elemente distincte din X. u7=(5. U ) este un graf G1= ( X . X fiind o multime finita si nevida de elemente numite noduri sau vârfuri.CAP IV GRAFURI ORIENTATE 1. spunem ca u si x sunt incidente. spunem ca x este extremitatea initiala.î.V) a. U ) Daca x si y sunt extremitatile arcului u.U) este un graf H=(Y. iar y este extremitatea finala a arcului. U ) a.3). iar vârfurile x si y sunt adiacente în G. la fel ca si u si y .2) u5=(4. u2=(2. Un graf partial al unui graf dat se obtine pastrând aceleasi vârfuri si eliminând o parte din arce. u6=(6. iar multimea de arce V este . u4=(4. Ex: 1 2 4 5 6 3 u1=(1. iar V contine toate arcele din U care au ambele extremitati în Y. Daca exista arcul u=(x. Vom spune ca subgraful H este indus sau generat de multimea de vârfuri Y. Fie graful de mai sus. VU. GENERALITATI: Definitie Se numeste graf orientat o pereche ordonata de multimi ( X. 70 . Graful se noteaza cu G= ( X . numite arce. U ).y) . adica G1 are aceeasi multime de vârfuri ca G. fie o submultime a acesteia. u3=(3.1).

u4) L2=(u1. u3.numim grad exterior al unui vârf x .: pentru n=3 avem 27 de grafuri orientate complete cu 3 vârfuri 1 3 2 1 3 2 Pentru grafurile orientate sunt doua tipuri de arce incidente cu un vârf: arce care”intra” si arce care “ies” din acel vârf. Ex.Definitie Se numeste graf complet cu n vârfuri un graf care are proprietatea ca orice doua vârfuri distincte sunt adiacente. putem construimai multe grafuri orientate având n vârfuri.(x)={y χ X / (y. numarul arcelor de forma (x. Acest lucru decurge din faptul ca doua vârfuri x. la grafurile orientate . u4) 4 u4 3 71 . iar pentru acestea exista 3 situatii ca ele sa fie adiacente.x) / u χ U } (multimea arcelor ce intra în x) Definitie Se numeste lant într-un graf orientat un sir de arce cu proprietatea ca oricare doua arce vecine au o extremitate comuna.y)χ U} (multimea succesorilor lui x) Ã. y sunt adiacente în mai multe situatii: exista arcul de la x la y.(x).: Fie graful 1 u1 u2 2 u3 L1=(u1. Se vor defini doua concepte diferite care sa corespunda numarului arcelor din fiecare din cele doua categorii: . deci C2n posibilitati de a alege 2 noduri distincte. Exista .y)χU (numarul arcelor care ies din x ).numim grad interior al unui vârf x si-l notam cu d.x)χ U} (multimea predecesorilor lui x) Si cu ù +(x)={u=(x. unde x= C2n Ex. Vom nota cu: Ã+ (x)={y χ X / (x.(x)={u=(y.exista arcul de la y la x si exista ambele arce. pentru un n dat. u2. notat cu d+ (x).:În definirea unui lant nu se tine cont de orientarea arcelor. Spre deosebire de grafurile neorientate la care exista un graf complet unic cu n vârfuri . Obs. rezulta ca .x)χU (numarul arcelor care intra în x ).y) / u χ U } (multimea arcelor ce ies din x) ù . . pentru un n dat sunt 3 x grafuri orientate complete cu n vârfuri. numarul arcelor de forma (y.

Definitie Se numeste circuit un drum care are x1=xn si arcele sunt distincte.cu exceptia primului si ultimului nod . 3} subgraful generat de multimea X2={4. 5). ….y Definitie Se numeste componenta conexa a unui graf orientat .Y1) al lui G care este tare conex si care este maximal în raport cu aceasta proprietate ( oricare ar fi x χ X \ X1.2). Ex.U). Definitie O componenta tare conexa a unui graf G =(X. subgraful lui G generat de X14 {x} nu mai este conex).y χ X exista un lant de extremitati x. (1.U) este un subgraf G1=(X1. Definitie Un graf orientat se numeste graf conex daca pentru oricare doua vârfuri distincte x.G=(X. circuitul se numeste circuit elementar. (6. Daca vârfurile drumului sunt distincte . 4. 72 unde X={1. 6} si U1={(1. un lant în care toate arcele au aceeasi orientare . xn} si se noteaza cu D.Definitie se numeste drum într-un graf orientat G=(X.Daca toate vârfurile circuitului.4)} 2 Graful G este conex El are o singura componenta conexa – graful însusi 2 5 Graful G1 nu este conex. 3.3).sunt distincte doua câte doua. un subgraf conex al sau maximal în raport cu aceasta proprietate(oricare ar fi un nod din subfraf nu exista lant între acel nod si vârfurile care nu fac parte din subgraf ).cu X= {x1.2). x2. 2. ( 3. 2). drumul se numeste drum elementar. 6} . unde X1={1.U). 3). (3. 1 3 4 G1=(X1. 3. (4. y χ X exista un drum de la x la y si un drum de la y la x. 4} si U={ (1. (2. U1) . 2.: Fie grafurile: G=(X. 5)} 1 3 4 6 sau pentru oricare doua Definitie Un graf se numeste tare conex daca x =1 vârfuri x. 5. 2. U). 5. el are doua componente conexe: subgraful generat de multimea X1={1.

xj )χ U daca( xi . Acest algoritm construieste matricea drumurilor pornind de la matricea de adiacenta a grafului si consta în urmatoarele: for k=1 to n for I=1 to n (i!k) for j=1 to n (j!k) if a[I. Matrici asociate grafului: 1.2. daca exista drum de la xi la xj în G mij= 0 . REPREZENTAREA GRAFURILOR ORIENTATE Pentru reprezentarea unui graf orientat se folosesc: 1. Matricea de adiacenta este matricea cea mai utilizata în reprezentarea unui graf orientat. xj ) χ U Matricea de adiacenta nu mai este obligatoriu simetrica.1.j]:=min(a[i.3. a[k.k]. 1.j]) endif endfor endfor endfor 73 . Matricea drumurilor. Matricea vârfuri-arce. Aceasta este un tablou bidimensional cu n linii si n coloane având elemente 0 sau 1 : 1 aij = 0 daca ( xi .j]=0 then a[I.2. unde: 1 daca xi este extremitate initiala a arcului uj bij = -1 daca xi este extremitate finala a arcului uj 0 daca xi nu este extremitate a arcului uj 1.se numeste matricea drumurilor asociata grafului G matricea M= (mij)nxm data prin: 1 .sau matricea de incidenta a grafului G . în caz contrar Un algoritm simplu de determinare a matricii drumurilor unui graf este algoritmul Roy-Warshall. ca în cazul grafurilor neorientate.este o matrice B=(bij )nxm .

k: 1.1.k]=1 si a[k.j]:3).x.i..nmax.j]. readln(x. Var a:array[1.nmax.j]=0 then a[i.n} este urmatorul: Program rw. readln(n). Programul Pascal de determinare a matricii drumurilor unui graf G=(X.1. i.j]=1 deci când exista drum de la xi la xk si drum de la xk la xj.Asadar un element al matricii a[i. begin init..k]*a[k. m:word.’:’).j. end..nmax] of 0.y). end end.y]:=1.nmax. a[x.. de arce:’).y:1.readln(m)..j ]=0 al matricii A devine 1 daca exista un nod k astfel încât a[i.. 74 . {initializeaza matricea de adiacenta} var i. procedure init.j]:=a[i. for j:=1 to n do write(a[i.de noduri:’).. Const nmax=100. end. begin writeln(‘dati nr. writeln(‘matricea drumurilor este:’) for i:=1 to n do begin writeln.. n. for k:=1 to n do for i:=1 to n do for j:=1 to n do if a[i. writeln(‘dati nr. for i:=1 to m do begin write(‘arcul ‘.U) cu X={1.

i]=0 2..j) presupune actualizarea new(p).2.next:=C[i]. Element=record nod:1.2. Initial for i:=1 to n do C[i]:=nil. Reprezentarea listelor folosind structuri dinamice de date: Se considera un vector C cu n componente de tip referinta. daca T[1. Listele de adiacenta pot fi reprezentate folosind tablouri sau structuri dinamice de date : 2.n] of integer cu urmatoarea semnificatie: § C[i]. next:reper end.i] este ultimul element din lista..indica coloana din T din care începe lista vecinilor lui i.Liste de adiacenta.1.i] -reprezinta un vârf.n] of reper. § T[1. C[i]:=p.2. § T[2. Existenta unui arc (i.n] of integer si un vector C:array[1. p: reper. p^..nod:=j. Sunt deci necesare urmatoarele declaratii: Type reper=^element.reprezinta adresa (coloana pe care se afla) urmatorul element din lista în care se afla T[1..i].i]. Reprezentarea listelor de adiacenta folosind tablouri: Se considera un tablou T:array{1.pentru orice vârf xχ X se construieste o lista L(x) a succesorilor sai. T[2. 75 .n.. C[i] pointeaza la începutul listei de adiacenta a lui i. var C:array[1. p^.1.

§ Determinarea drumurilor de lungime minima ( maxima) între oricare doua vârfuri. daca (xi. problema revine la determinarea drumurilor de durata minima. Pentru graful considerat se pot pune urmatoarele probleme: § Determinarea drumurilor de lungime minima ( maxima) între doua vârfuri xi. xj. U) si o functie l: U τR+ . notând ponderea cu l(u) . În continuare se vor prezenta algoritmi de obtinere a unor astfel de drumuri fara a determina toate drumurile dintre vârfurile grafului. etc. xj) este echivalenta cu existenta unui arc de lungime infinita care nu va interveni niciodata într-un eventual drum minim de la xi la xj. Daca vom considera drept noduri diferite puncte dintr-un oras.xj). unde u=(xi. Se vor prezenta în continuare urmatorii algoritmi: § Algoritmul lui Dijkstra § Algoritmul lui Roy-Floyd § Metoda drumului critic În capitolul cu aplicatii vor fi prezentati algoritmi în limbajul Pascal care ilustreaza utilizarea acestor algoritmi. daca l(u) reprezinta costul transportului de la xi la xj problema revine la determinarea drumurilor având costul de transport minim. DRUMURI MINIME SI MAXIME ÎN GRAFURI ORIENTATE Fie un graf orientat G=(X.xj)∀U l(xi. care asociaza fiecarui arc uχ U lungimea ( costul sau ponderea) sa cu l(u).3. iar inexistenta arcului (xi. Lungimea unui drum în acest graf este egala prin definitie cu suma lungimilor asociate arcelor sale.xj)χU Semnificatia acestei alegeri este urmatoarea: drumul cel mai scurt de la xi la el însusi este de lungime 0. Pentru tratarea problemelor de minim vom asocia grafului G o matrice a costurilor C=(cij )nxn definita astfel: cij = 0 + .xj) reprezinta durata de trecere de la xi la xj. Parcurgerea grafurilor orientate se realizeaza prin aceleasi metode care au fost prezentate la grafurile neorientate : DF si BF. Rezolvarea problemei determinarii unor drumuri de lungime minima într-un graf are multiple aplicatii practice. daca i=j daca (xi. § Determinarea drumurilor de lungime minima ( maxima) pornind dintr-un vârf dat la toate celelalte noduri. 76 .

( drumul de la 1 la 2 are lungimea 1 ). daca pentru un nod x j nu exista un astfel de drum . Pentru a retine si drumurile minime ( nu numai lungimile lor ) vom considera un vector PREC care retine indicele precedentului fiecarui nod în drumul minim de la x0 la acel nod si care se actualizeaza la fiecare modificare dj:=dk+C(k. Initial S={ x0 }. 2. daca xj χS lungimea drumului minim de la x 0 la xi. Dupa adaugarea lui xk în S trebuie actualizate valorile lui d. sa se determine toate vârfurile xi pentru care exista drum de la x0 la xi .1.U).precum si unul dintre drumurile minime de la x 0 la xi. 4) de lungime 5 ( drumul de la 1 la 4 are lungimea 5 ).dn) a. 2. ( drumul de la 1 la 3 are lungimea 4 ). Algoritmul utilizeaza metoda Greedy generând drumurile minime în ordinea crescatoare a lungimilor. 3.: 2 1 3 1 2 10 3 1 1 1 5 3 4 6 Pentru graful considerat . cu xpχ X \ S. 5. Pentru a alege nodul xk ce urmeaza a fi adaugat în S vom folosi un vector d=(d1.…. 3 ) de lungime 4. daca xi ∀ S Initial di = C(i0. ce foloseste numai vârfuri din S. plecând din nodul 1.4. ALGORITMUL LUI DIJKSTRA Problema: Fiind dat un graf orientat G=(X. Ex. D2=(1. 5.î. 2 ) de lungime 1. 2. D3=(1. De la 1 la 6 nu exista drum. În final vectorul d va contine costurile (lungimile) drumurilor minime de la x0 la celelalte noduri.j) PREC:=k. vom obtine în ordine: D1=( 1. ( drumul de la 1 la 5 are lungimea 2 ). o functie l: U τ R+ si un nod x0 . n unde C este matricea costurilor. Algoritmul în Pascal este prezentat în capitolul cu aplicatii. lungimea celui mai scurt drum .d2. La fiecare pas adaugam în S acel nod xk χ X \ S cu proprietatea ca drumul minim de la x0 la xk are cel mai mic cost dintre drumurile de la x0 la xp . Algoritmul se încheie când S contine toate nodurile pentru care exista drum de la nodul de plecare . 77 . dj= . D4=(1. di = lungimea drumului minim de la x0 la xi. Se considera S multimea vârfurilor xiχ X pentru care am gasit drum minim de la x0 la xj . i) … i= 1. 5 ) de lungime 2.

…. daca i=j 78 mij = . având nxn elemente) ale carei elemente d ij sunt multimi de noduri (d ij va reprezenta în final multimea nodurilor ce pot precede pe xj în drumul minim de la xi la xj). Se porneste de la matricea costurilor C : for k=1 to n for i=1 to n (i!k) for j=1 to n (j!k) cij :=min ( cjj . ALGORITMUL LUI ROY-FLOYD Problema: Fiind dat un graf G=(X. daca (xi.2. x2 . sa se determine pentru fiecare pereche de noduri x i .U) cu X={x1. Simultan cu determinarea lungimilor minime ale drumurilor pot fi retinute si acestea.4.xj) ∀U si (i!j) 0 . daca (xi. Acest algoritm de determinare a tuturor drumurilor minime între oricare doua vârfuri ale unui graf G va fi prezentat în capitolul cu aplicatii.. Pentru determinarea drumurilor de lungime maxima se ataseaza grafului o matrice M=(mij)nxn definita astfel: l( xi. xj (i!j) lungimea minima a drumurilor de la xi la xj precum si aceste drumuri (în caz ca exista drum de la x i la xj ). xn } si o functie l: UτR. Se va folosi o matrice D ( patratica . daca exista drum de la xi la xj daca nu exista drum de la xi la xj Determinarea matricii C este asemanatoare algoritmului Roy-Warshall pentru obtinerea matricii drumurilor. cik + ckj ) endfor endfor endfor Acest algoritm poate fi privit ca o succesiune de n transformari aplicate matricii C. daca i=j lungimea drumului minim de la xi la xj . xj) . Algoritmul Roy-Floyd determina lungimile minime ale drumurilor între oricare doua noduri ale grafului într-o matrice C= ( cij )nxn unde cij = 0.xj) χ U .

Algoritmii de determinare a drumurilor minime pot fi adaptati cu mici modificari pentru determinarea drumurilor maxime. Fie matricea M asociata grafului .n} vom avea multimea nodurilor ce pot precede pe xj într-un drum maxim de la xi la xj. cu diferenta ca . iar D=(dij ) nxn cu {xi} dij = Ô daca m ij > daca m ij = si (i!j) sau i=j for k=1 to n for i=1 to n (k!I) for j=1 to n (k!j) if m ij < m ik + m kj then m ij := m ik + m kj d ij := d kj else if m ij = m ik + m kj then d ij := d ij 4 d kj endif endif endfor endfor endfor În matricea M vom avea în final lungimile drumurilor maxime între oricare doua noduri. ….xj) . xj (i !j) pentru care nu exista arcul (xi. iar în d ij … I. În capitolul cu aplicatii va fi prezentat algoritmul de determinare a tuturor drumurilor maxime între oricare doua noduri folosind acest algoritm 79 . marcam în matrice .Aceasta matrice este asemanatoare matricii costurilor atasata grafului pentru determinarea drumurilor minime.j χ {1. pentru perechi de noduri xi..

C) si (B. Activitatile reprezentate de arcele (B.D).C) si (C. Nodul B reprezinta evenimentul ce marcheaza terminarea activitatii reprezentate de arcul (A. Ex.4.Critical Path Method. Metoda este cunoscuta sub denumirile: PERT.: C 4 2 7 1 2 A B D E Pentru graful de mai sus începerea lucrarii este reprezentata prin vârful A.B) si începerea activitatii reprezentate de arcele (B. 80 . DRUM CRITIC ÎNTR-UN GRAF DE ACTIVITATI Definitie : Un graf de activitati este un graf asociat unei lucrari complexe a carei realizare presupune desfasurarea mai multor actiuni( procese. Pentru a nu avea mai multe arce paralele si de acelasi sens între doua vârfuri ale grafului se introduc evenimente si activitati fictive. iar terminarea ei prin vârful E. arcele reprezinta etapele sau activitatile elementare ale lucrarii.D) se desfasoara în acelasi timp cu activitatea reprezentata de arcul (B. activitati ce se numesc activitati critice. nodul C este evenimentul ce marcheaza terminarea activitatii reprezentate de arcul (B.D). Atunci când construim un astfel de graf trebuie sa respectam urmatoarea regula: toate arcele care pleaca dintr-un vârf X reprezinta activitati ce nu pot începe decât dupa terminarea tuturor activitatilor reprezentate de arcele care sosesc în vârful X. Pentru un graf dat drumul critic nu este unic Drumul critic reuneste activitati a caror întârziere duce la întârzierea întregii lucrari. Pentru un astfel de graf nodurile reprezinta evenimente care pot fi interpretate ca indicând realizarea unor obiective partiale ale lucrarii . momentul începerii ei este reprezentat de extremitatea initiala. iar lungimea asociata unui arc –timpul de desfasurare a activitatii asociate acelui arc.D) etc. Calculul timpului de realizare a evenimentului final revine la cautarea în graf a drumului cel mai lung sau a drumului critic. Definitie : se numeste drum critic într-un graf de activitati un drum de lungime maxima care leaga nodul initial de nodul final. activitati). Pentru o activitate.Programme Evaluation and Research Task si CPM.C) si începerea activitatii reprezentate de arcul (C. iar momentul terminarii ei de extremitatea finala a arcului respectiv.

Teancuri de carti ( STIVA ): Biblioteca unui liceu primeste un numar de carti si vrea sa-i separe pe autori. p^.readln(cartea). Pentru fiecare autor se vor afisa titlurile cartilor si numarul de exemplare primit. inc(n). next:reper end. while p<>nil do begin writeln(p^. while p<>nil do if p^. n_ex:byte..cartea:string.exit end else p:=p^.autor).cartea).autor[n]:=autorul.next end end.Pentru fiecare eveniment putem vorbi de o data asteptata si de o data limita de realizare a sa.titlu. Scrieti un program care sa simuleze acesta activitate stiind ca autorii si titlurile cartilor se introduc de la tastatura pâna la CTRL\Z.write(’autorul: ’).next:=top[i]. begin p:=top[i].next.write(’autorul:’) 81 . procedure adauga(i:byte.n_ex:=1. new(p). procedure listare(top:reper. while not eof do begin readln(autorul). p^.n_ex). p:=p^.n:byte. write(’cartea:’).i:=indice(autorul).100] of reper. adauga(i. p^. var i:byte. top[i]:=p end. top:array[1. program carti. begin for i:=1 to 100 do top[i]:=nil. var p:reper.100] of string. CAP V APLICATII LISTE: 1.titlu:=cartea.’ ’. autor:array[1.titlu=cartea then begin inc(p^. var p:reper. n:=0..cartea:string). type reper=^carte.p^. begin writeln(’cartile ’.autor:string).indice:=n end. function indice(autorul:string):byte. begin for i:=1 to n do if autor[i]=autorul then begin indice:=i. p:=top. carte=record titlu:string.exit end. autorul.n_ex). var i.

repeat writeln(p^. p:=prim. 82 .cod). procedure iesire. program depozit.cod:=codul.prim^. procedure intrare. prim:=prim^. prim^.next until p=nil end end. procedure listare.next:=nil. comanda:char. E-iesirea unei loc.next:=nil. {adaugarea unui element} var codul:word. Dispecerizare locomotive ( COADA ): Se considera un depou de locomotive cu o singura linie de cale ferata cu o intrare si o iesire. begin write(’codul locomotivei: ’). if prim=nil then {coada este vida} begin new(prim). for i:=1 to n do listare(top[i]. p^. Llistarea si S. prim^.end. 2. p:=prim.next:=p. ultim.readln(codul). ultim:=prim. element=record cod:word. {traversarea cozii} begin if prim=nil then writeln(’depoul este gol’) else begin writeln(’locomotivele din depou sunt: ’). dispose(p) end end. var prim.oprirea programului . p^.Sa se scrie programul care realizeaza dispecerizarea locomotivelor prelucrând comenzi de forma: I-intrarea unei locomotive. ultim^. afisând locomotivele existente.cod). ultim:=p end end. next:reper end. type reper =^element. uses crt. end else {se adauga in coada un nou element} begin new(p). {stergerea primului element} begin if prim=nil then writeln(’depoul este gol’) else begin writeln(’iese locomotiva cu codul ’. p:=p^.autor[i]) end.cod:=codul. p:reper.next.

nume).next. readln(p^. {lista vida} write(’n=’). Câstiga jocul ultimul copil ramas în cerc. end until comanda=’S’ . readln end.Begin clrscr. var sant. Begin new(sant). ultim^.p^.Sa se simuleze jocul stiind n. case comanda of ’I’:intrare. prim:=nil. next:adresa end.next^} until p=p^. write(’m=’).p^. writeln(’ Castiga ’. comanda:=UpCase(comanda). repeat write(’comanda: ’).readln(n).next:=sant^. ultim^.next:=p. {coada se transforma in lista liniara} {simulam jocul} p:=sant. repeat for i:=1 to m-1 do p:=p^.next {stergem logic elementul p^.readln(m).m s numele copiilor.’L’:listare. readln end.nume). începând cu primul copil asezat în cerc si continuând în ordinea initiala în care au fost asezati . copil=record nume:string.next.i:byte.next. {numaram m copiii} writeln(’Iese copilul ’. writeln(’Copiii:’). ’E’:iesire.nume). ’S’.next^. p^.m. 3 Jocul lui Joseph ( LISTA CIRCULARA ): Un numar dat n de copii stau în cerc si numara . p:adresa. type adresa=^copil. 83 .Fiecare al m-lea copil iese din cerc. program Joseph. ultim:=p end. for i:=1 to n do begin new(p).next^.next:=p^. ultim.ultim:=sant. n. readln(comanda).

pred:=sant1. write(’numar: ’).info. Folosind o lista alocata dinamic : a) sa se afiseze numerele în ordinea citirii. type reper=^element.pred. sant1^.pred. 84 . sant2^.q:reper.’ ’). n.readln(n).next.pred:=p. p^.next:=sant2. while n<>0 do begin p:=sant2. element=record info:word. until p=sant1.new(sant2).info.info:=n. begin new(sant1). p:=sant2^. b) sa se afiseze nr în ordinea inversa citirii.’ ’).sant2. ( LISTA DUBLU ÎNLANTUITA – cu santinele): Se citesc de la tastatura mai multe nr naturale nenule <=35000. write(’numar: ’). pred.new(sant2).next. writeln(’b)’). sant2^. p:=p^. writeln end. p:=sant1^. p:=p^. program numere. sw:=1.next:=sant2. p^.next. c) sa se afiseze nr în ordine crescatoare.readln(n).sw:word. p:=sant1^. mai putin ultimul element care este 0. writeln(’a)’). end.p.4. next:reper end. while sw=1 do begin sw:=0. if p=sant1 then writeln (’lista vida’) else begin repeat write(p^. var sant1. if p=sant2 then writeln(’lista vida’) else begin repeat write(p^. writeln end. until p=sant2.

info:=p^.info. citite de la tastatura( pâna la CTRL\Z).n:=nr.info then begin sw:=1.info:=n end. ultim:=q end. nr:integer.info.’ ’). {cautam nr in lista} if p=nil then begin new(q). while p^. ultim^. program min_lista. p:=p^. writeln end. var q:reper.info>p^.next:=q.Numerele se pun în lista în ordinea citirii. Lista se va afisa înainte si dupa stergere.p:reper. begin p:=prim. p^. p:=p^. until p=sant2. q^.if p<>sant2 then begin repeat if p^. readln end.next.pred. p^. 5.next until p=sant2^.n:=p^. write(’c)’).n<>nr do p:=p^. if p=sant2 then writeln(’lista vida’) else begin repeat write(p^.next^. element=record n:integer. procedure adauga(nr:integer).next^. Stergerea elementului minim dintr-o lista ( LISTA SIMPLU ÎNLANTUITA ): Sa se creeze o lista de numere întregi distincte.info. Sa se determine valoarea minima din lista si sa se stearga elementul corespunzator. end end.next.next.ultim. 85 .next^. p:=sant1^. next:reper end. type reper=^element. var prim.

readln(nr). p:=adr_ant_min. Begin new(prim).next:=nil. adauga(nr) end. listare. procedure listare. begin writeln(’lista:’). while not eof do begin read(nr).n:=nr. ultim:=prim. writeln(’adauga numerele:’). p:=p^.’ ’). 5. while p<>nil do begin if p^.n<min then begin min:=p^.pmin:reper. listare.pmin^. Dispose (q) {elibereaza memoria} end. while p<>nil do begin write(p^. prim^.n). procedure stergere(p:reper). begin min:=Maxint. write(’primul nr este:’). prim^. p:=prim. begin q:=p^.next^. LISTA SIMPLU ÎNLANTUITA –cu santinela: 86 .next end. readln end. adr_ant_min:=pmin end. min:integer.next.n. var q:reper. p:=prim. {salvam adresa elementului care se sterge} p^:=q^.next^.next^. writeln(’minimul este ’. var p. writeln end. p:=p^.{adresa elem anterior celui minim} stergere(p). pmin:=p end.n.function adr_ant_min:reper.next end.

ultim.er:integer. for i:=1 to length(nr) do begin val(nr[i]. ultim^.inf:=val.er). type lista=^element. end end.i. Crearea si traversarea unui arbore binar: program parcurg_arbore. if val>0 then {subarborele este nevid} begin new(p). {adresa radacinii arborelui} function arbore:reper. write(’numarul este:’).next end. st. readln end.next:=nil. ultim^. p^. var rad:reper.suma). uses crt.’ ’). element=record info:integer. begin clrscr. while p<>nil do begin write(p^.{generarea radacinii p^ a subarborelui} 87 . new(p).info. Sa se alcatuiasca un program care creeaza o lista simplu înlantuita ce contine ca elemente cifrele pare ale numarului dat.Se citeste un numar natural ce contine maxim 200 cifre. p^. suma:=0.readln(nr). {returneaza adresa radacinii} var p:reper.cifra.p^.cifra. if cifra mod 2=0 then begin suma:=suma+cifra. begin read(val). p:=sant. program lista_sant. type reper=^nod. nod=record inf:byte. Programul va afisa elementele listei si suma elementelor sale. new(sant). var nr:string. suma.next:=nil.dr:reper end. val:byte. sant. p:=p^. ultim:=sant. ARBORI: 1. next:lista end.next:=p.info:=cifra. writeln(’suma este: ’.p:lista.

readln end. begin if p=nil then begin write(p^. p^.dr:=arbore. begin writeln(’nodul radacina:’). begin if p=nil then begin inordine(p^. procedure postordine(p:reper). inordine(rad).writeln(’arborele parcurs in preordine: ’). p^.write(’nodul din stg. end end. st. begin if p=nil then begin postordine(p^.{gen. procedure preordine(p:reper). {R} {S} {D} {S} {R} {D} {S} {D} {R} 2. nod=record cuvant:string[20]. nodului ’. var rad:reper.val. writeln.val. 88 . write(p^. type reper=^nod. nodului ’. procedure inordine(p:reper). inordine(p^. writeln. st.writeln(’arborele parcurs in inordine: ’).st).st). Arbore binar de cautare: program concordante.dr). preordine(p^. dr.inf:2). writeln. subarb. subarb.dr). cuv:string[20]. writeln.inf:2).dr). frecv:byte.{gen. begin if p<>nil then begin inordine(p^. end end. rad:=arbore. write(p^.dr:reper end. procedure inordine(p:reper). si-l leaga de rad} end else p:=nil.’:’). postordine(p^. preordine(p^. postordine(rad). arbore:=p.st). si-l leaga de rad} write(’nodul din dr. end end.st). preordine(rad).inf:2).st:=arbore. end.writeln(’arborele parcurs in postordine: ’).’:’).

st. begin if p=nil then begin new(p). type reper=^nod. begin rad:=nil.frecv). begin write(’nodul: ’). st:=nil. frecv:=1. if rad =nil then writeln(’Arbore vid’) else begin writeln(’Cuvintele cu frecventele lor: ’). inordine(p^. var rad:reper.frecv) else if cuv<p^. caut_adaug(rad). function arbore(n:byte):reper. 89 . nod=record inf:byte.’ ’. end.dr) end. ns.cuvant then caut_adaug(p^.nd:byte.dr) end end. inordine(rad) end.writeln(p^.dr:reper end. Crearea unui arbore perfect echilibrat: program creare. var p:reper.st) else caut_adaug(p^. 3. writeln(’Cuvintele :’). while not eof do begin readln(cuv). with p^ do begin cuvant:=cuv.p^. readln end.cuvant. dr:= nil end end else if cuv=p^. n:byte. procedure caut_adaug(var p:reper).cuvant then inc(p^.

{gen subarb dr cu nd noduri} if nd>0 then p^. nume:string.’:2). sa se afiseze cel mai apropiat stramos comun al celor doua persoane. {gen subarb st cu ns noduri} if ns>0 then p^.pp:reper.rad. nd:=n-ns-1. type reper=^nod. gen:byte. st. begin if p<>nil then begin write(p^.st:=arbore(ns) else p^. Program arbore_genealogic.dr:=nil. var rad. procedure preordine(p:reper).p. preordine(rad) end else writeln(’Arbore vid’).read(p^.q. uses crt.dr:=arbore(nd) else p^.tata:reper end. arbore:=p end.dr. g1.new(p). end. 4. Fiind date numele a doua persoane din familie . Arbore genealogic Se considera un arbore genealogic care cuprinde descendentii unei persoane.st). preordine(p^. writeln(’Arborele perfect echilibrat: ’).inf). begin write(’n= ’).g2:byte. preordine(p^.readln(n). 90 .} ns:=n div 2.inf:3).{gen. if n>0 then begin rad:=arbore(n).dr).st:=nil. nod=record nume:string. subarb. end else write(’. end.

nume:=nume. p:=pp. readln(nume) until gasit(rad). write(’Stramosul: ’). 91 .tata.nume=nume then begin gasit:=true. 2} if g1<g2 then repeat q:=q^. Begin clrscr.g) end end. var nume:string.st).g:byte). repeat write(’Persoana 2: ’). 1} g1:=q^.dr. repeat write(’Persoana 1: ’).tata:reper. until gasit(rad). function gasit(p:reper):boolean. q:=pp.p^.nume. creare(p^.g+1). write(’Primul fiu al lui ’.’:’).nume.p^.gen:=g. write(’Fratele lui ’. if nume=’’ then p:=nil else begin new(p). {g1=generatia pers. gasit:=gasit(p^.pp:=p end else begin g:=gasit(p^. readln(nume).nil.tata. {g2=generatia pers.exit end.st. creare(rad. g1:=p^. begin readln(nume).p.procedure creare(var p:reper. creare(p^.gen.0).’:’) .gen.dr) end else gasit:=false end.tata:=tata.tata. p^. dec(g2) until g1=g2 else if g1>g2 then repeat p:=p^. var g:boolean. dec(g1) until g1=g2. if g then begin gasit:=g. begin if p<>nil then if p^.

niv+1).. q^.niv+1). var r.inf:=min(q^.tata end.x. var p:reper. readln end.inf.st.niv:integer).tata. type reper=^nod. while dk<n do begin dk:=dk*2. end else if y<>0 then begin 92 .inf:=min(q^.q^.dk:integer).dr:reper end.niv+1).dr. function min(x.v.dr. creare(q^. procedure creare(var q:reper. q:=q^. 5. q^.while p<>q do begin p:=p^. Arbore de sortare: Sortarea unui sir de numere prin selectie arborescenta.st^.20] of integer.dr^.st. writeln(’Stramosul comun cel mai apropiat este: ’.inf). n. begin if x<y then min:=x else min:=y.dk.u. r:=-1.q^. r:=r+1 end end. creare(q^.inf) end else if niv=r then begin u:=u+1.niv+1).st^. end.p^. if u<=x div 2 then begin new(q).i:integer. st. program arb_sortare.y.nume).inf. creare(q^. begin dk:=1. procedure calcul(n:integer.y:integer):integer. creare(q^.r. a:array[1. begin if niv<r then begin new(q). nod=record inf:integer.dr^.

q^.inf.dr^. begin if q^.r.st^. writeln(’Sir ordonat’). type reper=^nod. q^. procedure cautare(q:reper). q^. a[1]:=p^.. u:=0. end. writeln(’Dati sirul’). end end.inf end. nod=record v:char.inf:=a[v]. x:=n-y.0).inf:=maxint else if q^.v:=0. c:char. rad:reper.st:=nil. q^.dr:=nil. end. 93 . var n. st. begin c:=sir[i].inf=q^.i:byte.inf<>maxint then begin if q^. q^.inf.inf) end end. for i:=2 to n do begin cautare(p).st^. procedure getchar. 6.inf:=min(q^.q^. calcul(n. q^.inf then cautare(q^. Forma poloneza a expresiilor aritmetice: program forma_pol.’ ’).readln(n). new(q). begin write(’n=’). sir:array[1.dr:reper end.v:=v+1.st=nil then q^.dr:=nil end end else begin v:=v+1.inf:=a[v]. i:=i+1. q^. for i:=1 to n do read(a[i]).dk). creare(p. for i:=1 to n do write(a[i]. y:=dk-n.dr). new(q). a[i]:=p^.st:=nil.30] of char.st) else cautare(q^.

forward.’/’] do begin new(r). r^. r^. procedure termen(var r:reper). r^. while c in [’*’. var p:reper. end end. var p:reper.procedure factor(var r:reper).dr). begin putere(r). procedure factor(var r:reper). while c in [’+’. putere(r^. var p:reper.st:=p. p:=r. begin termen(r).st:=p.st:=p.dr). p:=r. factor(r^. p:=r. procedure putere(var r:reper). if i<=n then getchar. if i<=n then getchar. p:=r. begin factor(r). end end. p:=r.v:=c.dr).v:=c. procedure exp(var r:reper). while c=’^’ do begin new(r). begin 94 . var p:reper. termen(r^. end end. p:=r.’-’] do begin new(r). procedure putere(var r:reper). r^.v:=c. r^. r^.forward.forward. procedure termen(var r:reper).

m). r^. end.20] of integer.20] of integer. afisare(rad). procedure afisare(r:reper).st). end end. afisare(r^.getchar..exp(rad). A:array[1. begin write(’n. readln end. for i:=1 to n do for j:=1 to n do A[i. var viz:array[1. r^. C:array[1. r^.dr:=nil end..v:=c. GRAFURI NEORIENTATE 1.i.m=’).j. if c=’(’ then exp(r) else begin new(r).readln(n.20] of 0.st:=nil. i:=1.x. writeln(’Forma poloneza prefixata: ’).dr).1. begin if r<>nil then begin write(r^.. writeln(’Dati expresia: ’).u. for i:=1 to m do begin 95 .v:integer.p. afisare(r^.m.v).y.20.j]:=0.. Parcurgerea BF: program parcurgere_BF. readln(n). begin write(’Lungimea expresiei=’)..1. n. for i:=1 to n do read(sir[i]).

write(’muchia ’,i,’=’); readln(x,y); A[x,y]:=1;A[y,x]:=1; end; write(’varful de plecare : ’);readln(i); for j:=1 to n do viz[j]:=0; C[1]:=i; p:=1;u:=1; viz[i]:=1; while p<=u do {coada nu este vida} begin v:=C[p]; for j:=1 to n do if (A[v,j]=1) and (viz[j]=0) then begin u:=u+1; C[u]:=j; viz[j]:=1 end; p:=p+1 end; write(’lista varfurilor in parcurgere BF , plecand din ’,i,’ este: ’); for j:=2 to n do write(C[j],’ ’); writeln; readln end.

2. Parcurgerea DF:

program parcurger_DF; var viz:array[1..20] of 0..1; A:array[1..20,1..20] of integer; n,m,k,ps,i,j,x,y:integer; S,urm:array[1..20] of integer; begin write(’n,m=’);readln(n,m); for i:=1 to n do for j:=1 to n do A[i,j]:=0; for i:=1 to m do begin write(’muchia ’,i,’=’);readln(x,y); A[x,y]:=1;A[y,x]:=1; end; write(’varful de plecare: ’);readln(i); for j:=1 to n do begin 96

viz[j]:=0; urm[j]:=0 end; S[1]:=i;ps:=1; viz[i]:=1; write(’lista varfurilor in parcurgere DF plecand din ’,i,’ este:’); while ps>=1 do begin j:=S[ps]; k:=urm[j]+1; while(k<=n) and ((A[j,k]=0) or (A[j,k]=1) and(viz[k]=1)) do k:=k+1; urm[j]:=k; if k=n+1 then ps:=ps-1 else begin write(k,’ ’); viz[k]:=1; ps:=ps+1; S[ps]:=k; end end; readln end.

3. Grafuri euleriene ( verificarea faptului ca un graf este eulerian):

program verif; var eulerian:boolean; e,gr,c,c1:array[1..20] of integer; a:array[1..20,1..20] of integer; n,m,i,j,k,k1,x,y,l:integer; viz:array[1..20] of byte; function vf_iz :boolean; {val este true daca graful are vf izolate} var i,j,s:byte; begin vf_iz:=false; for i:=1 to n do begin s:=0; for j:=1 to n do s:=s+a[i,j]; 97

gr[i]:=s; if s=0 then begin vf_iz:=true; break; end; end; end; function grade_pare:boolean; {are val true daca gradele tuturor} var i:byte; { varfurilor sunt numere pare} begin grade_pare:=true; for i:=1 to n do if odd(gr[i]) then begin grade_pare:=false; break end; end; function conex:boolean; {are val true daca graful este conex} var b,viz:array[1..20] of byte; i,j,p,u,v:byte; begin for j:=1 to n do viz[j]:=0; b[1]:=1; p:=1;u:=1;viz[1]:=1; while p<=u do begin v:=b[p]; for j:=1 to n do if (a[v,j]=1) and (viz[j]=0) then begin u:=u+1; b[u]:=j; viz[j]:=1 end; p:=p+1; end; conex:=true; for i:=1 to n do if viz[i]=0 then begin conex:=false; break; end; end; Begin write(’n,m=’);readln(n,m); for i:=1 to n do for j:=1 to n do a[i,j]:=0; writeln(’dati muchiile grafului: ’); for i:=1 to m do begin write(’mucjia ’,i,’=’);readln(x,y); a[x,y]:=1;a[y,x]:=1; end; eulerian:=not vf_iz and grade_pare and conex; if not eulerian then writeln(’graful nu este eulerian’) else begin {se construieste in C primul ciclu} writeln(’graful este eulerian’); c[1]:=1; 98

10] of integer.q:integer.p.k.n=’). for i:=1 to m+1 do write(’ ’. m. gr[j]:=gr[j]-1. var x:array[1. while k>1 do 99 ..n).1. x[1]:=1. Grafuri hamiltoniene(se determina toate ciclurile hamiltoniene dintr-un graf ): program hamiltonian.readln(p.k.x[2]:=1. k:=2.q]:=0.q).j. 3. writeln(’ciclu eulerian: ’).c[i]).a[q.v.n.j]=1 then begin k:=k+1.{se depl elem in C} for j:=1 to k1-1 do c[j+l]:=c1[j+1]. for k:=1 to m do begin write(’muchia ’. sol:=0. readln end.10] of integer. end.sol.q]:=1.i. end. for j:=k downto l do c[j+k1-1]:=c[j]. for p:=1 to n do for q:=1 to n do a[p.. repeat for j:=1 to n do if a[c[k]. gr[c1[k1-1]]:=gr[c1[k1-1]]-1.’= ’). a[c[k-1]..c[k-1]]:=0.j]:=0 . a[j.k:=1. a:array[1. a[p. c[k]:=j.readln(m.p]:=1 end. begin write(’m. break. k:=k+k1-1.10. until c1[k1]=c1[1].

begin v:=0.readln(n. end. writeln. Algoritmul lui Dijkstra.m. LL:word.20] of word. {C= multimea varfurilor candidate la solutia la solutia S} vf_ant:array[1.i0:’)..m. { d[i]= lungimea minima a lanturilor de la i0 la i} C:array[1. if sol=0 then write(’graful nu este hamiltonian’). for i:=1 to k-1 do if x[k]=x[i] then begin v:=0.i0). end. dd:word. if sol=1 then writeln(’ cicluri hamiltoniene :’). for j:=1 to n do write (x[j]). end. 4.j.k:byte.x[k]]=0 then v:=0.m:byte. begin write(’n. end else if k<n then begin k:=k+1.20] of boolean. var L:array[1. {vf_ant[i]=anteriorul lui i pe lantul minim} i.20] of byte. v:=1.x[1]]=1) then begin sol:=sol+1. x[k]:=1. readln. var i. if v=0 then k:=k-1 else if (k=n) and (a[x[n]. if a[x[k-1].20. 100 .i0. {L-lungimile muchiilor} d:array[1. while (x[k]+1<=n) and (v=0) do begin x[k]:=x[k]+1.1.n.20] of word.j.... break end.. end. procedure citire.lanturi minime într-un graf neorientat : program lanturi_minime. {ALGORITMUL LUI DIJKSTRA} const inf=65535.

L[i. procedure initializari.i0. begin citire.j]>0 {vf_ant j este adiacent cu i0 } then begin d[j]:=L[i0. for i:=1 to n do C[i]:=true. d_min:=min. var i:byte.writeln end end. end end. for j:=1 to n do if C[j] then if d[j]<min then begin min:=d[j]. while d_min(i)<inf do begin C[i]:=false. for k:=1 to m do begin readln(i.i0.j]:=LL. begin for i:=1 to n do d[i]:=inf. L[j. initializari. i:=j end. for j:=1 to n do if L[i0. procedure lant_minim(i:byte).d[i]:2. for j:=1 to n do if C[j] and (L[i. C[i0]:=false. vf_ant[j]:=i0. d[i0]:=0.write(’muchiile si lungimile lor:’). ’la ’. begin if i<>i0 then lant_minim(vf_ant[i]). end. end. var i. {d_min =min(d[j]) } min:word. function d_min(var i:byte):word.LL).j]>0) then begin 101 . begin min:=inf. end.i]:=LL.j:byte.i). procedure scriere. write(i:3).i) else begin write(’lantul minim de la ’. var j:byte. write(’de lungime =’. lant_minim(i).’ este:’).j].’la ’.j. begin for i:=1 to n do if i<>i0 then if C[i] then writeln(’Nu exista lant de la ’. {i0 apartine lui S} end.

20] of boolean. end.i. end end.oras_prec.i]:=dd..D[j. for j:=1 to n do if neales[j] and (D[i.j]<min) then begin min:=D[i. c[1]:=k.1. begin write(’n=’).dd:=d[i]+L[i. {D-matricea distantelor dintre orase} c. for i:=1 to n-1 do for j:=i+1 to n do begin write (’distanta dintre orasele ’. var j. neales:array[1.j]:=dd.20] of byte..cmin:array[1. dmin.n.maxlongint.j.jmin:byte. vf_ant[j]:=i end end end.j. dist:=0. var D:array[1.20. 5. function oras_dist_min(i:byte):byte. for i:=2 to n do begin oras_prec:=c[i-1]. k. type natural=0..min:word..dist:natural. procedure citire. var i:byte.20] of word..{det euristic ciclul minim care pleaca din k} begin for i:=1 to n do neales[i]:=true.’si ’. if dd<d[j] then begin d[j]:=dd. oras_dist_min:=jmin. readln(dd). D[i. scriere end.j].readln(n). function dist_ciclu(k:byte):natural. Problema comis –voiajorului: program comisv.oras:byte. var i. begin min:=65535. neales[k]:=false.’=’). jmin:=j end.k:byte.j]. dd:word. 102 .

write(’traseul minim are lungimea= ’. dist_ciclu:=dist.prec:array[1. g:boolean.z. 103 .oras] end.m. end.x. s.i:integer. var m. begin citire. 4. end.nmax.j.d.oras:=oras_dist_min(oras_prec). dist:=dist+D[oras_prec.1. GRAFURI ORIENTATE 1. lungimea celui mai scurt drum precum si unul dintre drumurile minime de la x0 la xi program dijkstra.readln end.arc.i.. const nmax=15. inf=maxint div 2.dmin).neales[oras]:=false. procedure min( var k: integer). k. writeln(cmin[1]:3).nmax] of integer. c[i]:=oras. var c:array[1.n.xp:integer.k]. Algoritmul lui Dijkstra: Sa se determine pentru toate vârfurile xi ale unui graf orientat pentru care exista drum de la x0 la xi . dmin:=maxlongint. for k:=1 to n do write(cmin[k]:3). dmin:=dist end.y. writeln(’si trece prin orasele :’). if dist< dmin then begin cmin:=c.nmax] of integer. for k:=1 to n do begin dist:=dist_ciclu(k). dist:=dist+D[oras...

writeln( ’dati nr de arce: ’). writeln.j]:=inf. end else writeln end. if c[xp. for i:=1 to n do for j:=1 to n do c[i. write(i). begin if i<>0 then begin drum(prec[i]).i). if (d[k]=inf) or (x=n) then g:=false else begin s[k]:=1. s[i]:=0. end. end. end else begin 104 .’ si lungimea: ’). procedure drum(i:integer). for i:=1 to n do if (s[i]=0) and (d[i]<m) then begin m:=d[i]. x:=x+1.j]) then begin d[j]:=d[k]+c[k.y]:=z. k:=i end end.begin m:=inf*2. for i:=1 to n do begin d[i]:=c[xp. begin writeln(’dati nr de noduri:’). readln(x.z).readln(n). ’la’.i].j]. end. prec[xp]:=0. end. g:=true. for i:=1 to arc do begin write(’dati arcul ’. for i:=1 to n do if i<>xp then if d[i]=inf then begin write(’nu exista drum de la ’.readln(arc). repeat min(k).i.i]< inf then prec[i]:=xp else prec[i]:=0. for i:=1 to n do c[i.y. read(xp). xp. s[xp]:=1. x:=0. for j:=1 to n do if(s[j]=0) and(d[j]>d[k]+c[k. prec[j]:=k.i]:=0. c[x. until (not g).

nmax. drum(i).z).c[x.xp. begin write(’dati nr de noduri :’).j: integer. Algoritmul lui Roy-Floyd .j]:=[].i]:=0 end. inf=maxint div 2.i. write(’ dati nr de arce: ’). {c-initial matricea drumurilor} d:array[1.readln(m).j]:=[i] else d[i.nmax. begin if i<>j then begin for k:=1 to n do if k in d[i.y]:=z.. end end.j. {genereaza in vectorul dr un drum minim de la i la j pornind din nodul j} var k:word. procedure drum(i..writeln(’drum minim de la’.k. for i:=1 to m do begin write(’extremitatile si lungimea arcului ’.i).nmax] of 1.nmax. 2.1.1.readln(n). var c:array[1. const nmax=20. {initializeaza matricea costurilor C} var i. begin for i:=1 to n do for j:=1 to n do if (c[i.j]<inf)and (i<>j) then d[i.z:word. {initializeaza matricea D} var i.determinarea tuturor drumurilor minime între oricare doua vârfuri ale unui graf : program roymin.nmax.i.y. n.’:’). procedure initd..nmax] of multime. procedure initc.x. dr:array[1.j:integer). 105 ..’ la ’.nmax] of word. writeln end end. end.m..j. c[i.. readln(x.j]:=inf. for i:=1 to n do begin for j:=1 to n do c[i. type multime=set of 1.j] then begin lg:=lg+1.y..lg:word.

for k:=lg downto 1 do write(dr[k]:4) end end.k).i.j]:=d[i.j.k]+c[k. dr[1]:=j. drum(i. var i.’si’. lg:=lg-1 end.j:word.j] then begin c[i.j) else begin writeln(’lungimea drumurilor minime de la ’.j].dr[lg]:=k.j) end end end end. drum(i. if i<>j then begin lg:=1.j].j] then d[i.j].c[i.k]+c[k.j]:=c[i. d[i.i.j]=c[i. procedure afisare. if c[i. initd. afisare.j]=inf then writeln(’nu exista drum intre’.’este’.j]:=d[k. {afisarea rezultatelor} begin for i:=1 to n do for j:=1 to n do begin writeln.j]+d[k. end.j]>c[i. end else begin writeln. begin initc.k]+c[k. end else if c[i.j]).’la’. 106 . for k:=1 to n do for i:=1 to n do for j:=1 to n do if c[i.

nmax] of 1. for i:=1 to m do begin write(’extremitatile si lungimea arcului ’.nmax.j]:=[].j] then begin lg:=lg+1. {genereaza in vectorul dr un drum minim de la i la j pornind din nodul j} var k:word.’:’).j. begin write(’dati nr de noduri :’). procedure initd. var c:array[1.. for i:=1 to n do begin for j:=1 to n do c[i.j:integer)..lg:word.j]>inf)and (i<>j) then d[i.j.y.i.j: integer. begin if i<>j then begin for k:=1 to n do if k in d[i. for k:=lg downto 1 do 107 .readln(n).1.. Determinarea tuturor drumurilor maxime între oricare doua noduri ale unui graf orientat: program roymax.. const nmax=20. readln(x. end.nmax] of multime. end end.1. lg:=lg-1 end.j]:=inf.nmax.readln(m).i]:=0 end. write(’ dati nr de arce: ’).3.y]:=z. drum(i. n.nmax.. {c-initial matricea drumurilor} d:array[1. {initializeaza matricea costurilor C} var i.k). procedure initc. type multime=set of 1. dr:array[1. inf=maxint div 2.. dr[lg]:=k.x.m.. c[i.c[x. end else begin writeln. begin for i:=1 to n do for j:=1 to n do if (c[i.nmax] of word.z:word.j]:=[i] else d[i. {initializeaza matricea D} var i.k.z).y. procedure drum(i.nmax.i.

afisare. var i.. de activitati:’).i.j]=inf then writeln(’nu exista drum intre’.1.’este’.nmax] of real. if i<>j then begin lg:=1.. procedure citire. inf=maxint.c:real.j]. end else if c[i.j] then d[i. drum(i. procedure afisare.write(dr[k]:4) end end. const nmax=20. {afisarea rezultatelor} begin for i:=1 to n do for j:=1 to n do begin writeln.nmax.x. if c[i. dr[1]:=j._Metoda drumului critic într-un graf de activitati: program drcritic.’la’.tb:array[1.j]:=d[i.j] then begin c[i.k]+c[k.j.’si’.j]<c[i.j) else begin writeln(’lungimea drumurilor minime de la ’.j].j:word. var l:array[1. 108 . 4.nmax] of real.k]<>inf) and (c[k.j].j]+d[k. initd.k]+c[k. d[i. {citeste arcele si duratele asociate acestora} var i.m..j]=c[i.y:word.c[i.j]).j]:=d[k. for k:=1 to n do for i:=1 to n do for j:=1 to n do if(c[i. begin writeln(’dati nr.j]<>inf)then if c[i.k]+c[k.i. end. {in t se retin datele asteptate iar in tb datele limita de realizare a evenimentelor} n. t. begin initc.j:word.i.j]:=c[i.j) end end end end.

i]>=0 then begin if t[j]<0 then calct(j).j]) then writeln(’activitatea reprezentata de arcul :(’. end. {calculeaza recursiv elementul t[i]} var max: real.j] then min:=tb[j]-l[i.citire. if max<l[j.j:word. begin if i=n then tb[i]:=t[i] else begin min:=inf. t[i]:=max end end.i. calct(n). for j:=1 to n do if l[j.readln(m).’.j:word. procedure calct(i:word).’ si durata acesteia:’).’. begin if i<2 then t[1]:=0 else begin max:=0. for i:=1 to n do for j:=1 to n do if (t[i]=tb[i])and(t[j]=tb[j])and(t[j]=t[j]+l[i. calctb(1).i.i]+t[j] then max:=l[j. 109 .i).j]>=0 then begin if tb[j]<0 then calctb(j).c).i]+t[j] end. writeln(’EVENIMENTELE CRITICE SUNT:’).j]:=-1 end. l[x. for j:=1 to n do if l[i. for i:=1 to n do if t[i]=tb[i] then writeln(’evenimentul ’.’)’).y]:=c end. writeln(’ACTIVITATILE CRITICE SUNT:’). procedure calctb(i:word).{calculeaza recursiv elementul tb[i]} var min:real. tb[i]:=-1.j].y. end. tb[i]:=min end end. end.j.’. for j:=1 to n do l[i. for i:=1 to m do begin writeln(’dati arcul asociat activitatii nr. begin writeln(’dati nr de evenimente ale lucrarii:’). for i:=1 to n do begin t[i]:=-1. readln(x.readln(n). if min>tb[j]-l[i.

dr.graph. function earb(n1.y+30) end.st<>nil then begin line(x. a:arbore. var k.y:integer).n2:integer):arbore.n2) then begin earb:=true. afisare(a^.i.gm.x. c:char. varf=record st. var i:integer.gd.dr<>nil then begin line(x.n2:integer):boolean. begin if (n2=n1+2) and (s[n1]=1) and (s[n1+1]=2) and(s[n2]=2) 110 . afisare(a^.dr:arbore end.y. type arbore=^varf.y.n:integer.y+30) end end end.x+30. if a^.st. s:array[ 0. function constr(n1.. Desenarea arborilor binari cu un numar fixat de vârfuri: program arb_bin. begin earb:=false.x+30.20] of integer. a:arbore. begin if a<>nil then begin if a^. procedure afisare(a:arbore.y+30). exit end end.n2) then earb:=true else for i:=n1+3 to n2-3 do if (s[n1]=1) and earb(n1+1.5.x-30. var i:integer.y+30).i) and earb(i+1.n2-1) then earb:=true else if(s[n1]=1) and (s[n1+1]=2) and earb(n1+2.x-30. if(n2=n1+2) and (s[n1]=1) and (s[n1+1]=2) and (s[n2]=2) then earb:=true else if (n2>n1+2) then if (s[n1]=1) and (s[n2]=2) and earb(n1+1. uses crt.

repeat until keypressed. cleardevice. begin clrscr. while k>=0 do if k=2*n then begin if earb(1. initgraph(gd. detectgraph(gd. s[2*n+1]:=2. constr:=a end else if (s[n1]=1) and (s[n1+1]=2) and earb(n1+2. dec(k) end 111 .gm). begin if a<>nil then if (a^. procedure stergere(var a:arbore).n2) then begin new(a).dr:=constr(n1+2.2*n+1).n2).dr:=nil.0).dr=nil) then begin dispose(a).dr:=constr(i+1.n2-1). stergere(a) end end.n2).a:=nil end else begin stergere(a^. a^.a^.n2) then begin new(a). a^.dr).st:=constr(n1+1.st:=constr(n1+1. a^. a^. constr:=a end else for i:=n1+3 to n2-3 do if (s[n1]=1) and earb(n1+1.exit end end.gm.constr:=a end else if (n2>n1+2) then if (s[n1]=1) and (s[n2]=2) and earb(n1+1.st:=nil.i) and earb(i+1. stergere(a^. constr:=a.then begin new(a).dr:=nil.300.st). a^.a^.k:=0.’c:\bp\bgi’).2*n+1) then begin a:=constr(1. writeln(’numarul de varfuri :’).n2-1) then begin new(a).readln(n).st:=nil. for i:=0 to 2*n do s[i]:=0. a^. stergere(a) end. c:=readkey.i).st=nil) and (a^. afisare(a.

closegraph. BIBLIOGRAFIE 1. Doina Rancea Limbajul Pascal. dec(k) end. Cornelia Ivasc .Mona Pruna 112 . readln end. inc(k) end else begin s[k+1]:=0.Algoritmi fundamentali Computer Libris Agora 1999 2.else if s[k+1]<2 then begin inc(s[k+1]).

Valeriu Iorga Tehnici de programare Editura Teora. Eugenia Kalisz. algoritmi si programe Editura ALL Bucuresti.Bucuresti 1995 3.Bucuresti-1997 5.Bucuresti-1974 6. Bucuresti. Knut D. Barbu. Octavian Patrascoiu.1997 8. Ghe. Tratat de programarea calculatoarelor. Gheorghe Marian. Tudor Sorin Tehnici de programare-1996 113 . Irina Athanasiu.Bazele informaticii. Algoritmi fundamentali Editura Tehnica. Ioan Tomescu Data Structures Editura Univ. Ion Vaduva Bazele Informaticii Editura Tehnica-Bucuresti.1997 7.1994 4. Valentin Cristea. Metode.E.Grafuri si Elemente de Combinatorica Editura Petrion . Nicolae Mitroi Elemente de grafuri si combinatorica.

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->