Sunteți pe pagina 1din 78

Introducere

Evoluia sistemelor de calcul i a limbajelor de programare a determinat varietate i evoluie n descrierea i elaborarea algoritmilor. De altfel, reprezentarea algoritmilor i limbajele de programare s-au influenat reciproc. Pn la apariia i rspndirea structurilor de control (deceniul 70), reprezentarea algoritmilor s-a realizat prin limbajul schemelor logice i "prin pai" care necesitau utilizarea instruciunii de salt (go to <eticheta>). Sintaxa i semantica limbajelor de programare din acea perioad se supuneau acestei restricii (apariia i dezvoltarea unui numr mare de limbaje de programare - la un moment dat existau peste 200 de limbaje de programare - se datoreaz i cutrii eliminrii salturilor din procesele de calcul). Cercetrile, experienele i implementrile au durat peste 20 de ani. Algoritmica (reprezentarea i elaborarea algoritmilor) i Programarea (elaborarea i implementarea programelor) au fost nevoite s creeze un "front comun" pentru implementarea structurilor de control i construirea primelor limbaje de programare moderne: limbajul Pascal (1972, Niklaus Wirth, University of Zurich) i limbajul C(1972, Dennis Ritchie, AT&T Bell Laboratories). Apariia acestor limbaje a impus limbajul pseudo-cod (Pseudo-Code Language) n domeniul reprezentrii i elaborrii algoritmilor. Mai tarziu, evoluia reelelor de calculatoare i dezvoltatea reelei Internet, precum i implementarea unei versiuni perfecionate a limbajului C (versiunea C++), au condus la apariia i utilizarea pe scar larg a limbajului Java, concomitent cu apariia i dezvoltarea unor sisteme de operare moderne: Unix, Linux,Windows. C este un limbaj relativ "de nivel inferior". Aceast caracterizare nu este peiorativ; ea nseamn pur i simplu c C opereaz cu aceeai clas de obiecte cu care lucreaz majoritatea calculatoarelor, si anume caractere, numere i adrese. Acestea pot fi combinate i prelucrate cu operatori aritmetici i logici implementai pe calculatoarele actuale. C nu posed operaii pentru a prelucra direct obiecte compuse, cum ar fi iruri de caractere, mulimi, liste sau tablouri considerate ca un ntreg. Limbajul nu definete nici o alt facilitate de alocare de memorie n afar de definiiile statice i de lucrul cu stiv folosite de variabilele locale ale funciilor; nu exist colecii reziduale sau de grmezi ca n Algol68. Limbajul C folosete pointeri i are abilitatea de a face aritmetica cu adrese. Argumentele funciilor sunt pasate copiind valoarea argumentului i este imposibil pentru funcia apelat s modifice argumentul real din apelant. Cnd se doreste s se obin un "apel prin referin", se trimite explicit un pointer, iar funcia poate modifica obiectul la care puncteaza pointerul. Numele de tablouri sunt trimise ca locaie a originii tabloului, aa c rgumentele tablouri sunt efectiv apeluri prin referin. Orice funcie poate fi apelata recursiv si variabilele sale sunt create nou cu fiecare invocare. Definiiile de funcii nu pot fi imbricat, dar variabilele pot fi declarate n maniera de bloc structurat. Funciile unui program C pot fi compilate separat. Variabilele pot fi interne unei funcii, externe dar cunoscute numai ntr-un singur fiier surs, sau complet globale. Variabilele interne pot fi automate sau statice. Variabilele automate pot fi n registre pentru eficien mrit, dar declaraia de registru este numai intern compilatorului i nu se refer la vreun registru specific al calculatorului. -1-

Un pointer este o variabil care conine adresa unei alte variabile. Pointerii sunt foarte mult utilizai n C parte pentru c uneori sunt singura cale de rezolvare a unei anumite probleme, parte pentru c folosirea lor duce la alctuirea unui cod mai compact i mai eficient dect altul obinut n alt mod. Pointerii au fost "ngrmdii" la cteva instruciuni goto ca un minunat mod de a crea programe "imposibil" de priceput. Acest lucru devine pe deplin adevrat atunci cnd pointerii sunt folositi neatent, fiind usor de creat pointeri care s pointeze n locuri cu totul neateptate. Ca metod, pointerii se utilizeaz pentru un plus de simplitate. Utilizarea eficient a memoriei unui calculator presupune, n cazul programelor complexe, trecerea de la alocarea memoriei n timpul compilrii la alocarea necesarului de memorie al unui program pe timpul execuiei acestuia. Exist dou avantaje principale n urma unei astfel de treceri, i anume : memorie suplimentar pentru programe i posibilitatea de a utiliza aceast memorie pentru realizarea unor structuri dinamice de date. Dezavantajul major l constituie necesitatea de a nelege pe deplin modul n care se realizeaz alocarea dinamic a memoriei. O soluie de implementare a listelor liniare este sub forma unei nlnuiri de elemente cu aceeai structur, aflate n memorie la diverse adrese i legate ntre ele prin intermediul pointerilor. Scopul utilizrii listelor este de a economisi spaiu de memorie, motiv pentru care se folosete alocarea dinamic n locul celei statice (utilizat n cazul tablourilor). Accesul la un element al listei se poate face doar secvenial, parcurgnd elementele aflate naintea sa n nlanuire. Pentru a exploata avantajul listelor n ceea ce privete economia de spaiu de memorie, trebuie acordat o atenie deosebit operaiilor asupra listei. n general, asupra unei liste se pot face operaii de inserie/adugare de noduri, tergere de noduri i parcurgerea nodurilor. Aceast lucrare i propune s prezinte structurile i tehnicile de baz folosite n construirea listelor liniare, utiliznd o combinaie de explicaii, desene, secvene de cod i exerciii. Studierea listelor liniare este folositoare deoarece listele liniare reprezint o structur de date care poate fi folosit n aplicaii reale. Prezentarea punctelor forte, precum i a celor slabe ale listelor liniare, va oferi elevilor posibilitatea de a aprecia unele probleme legate de timp, spaiu i cod surs, pe care ar trebui s i le adreseze relativ la orice structur de date n general.. Lucrarea de fa se dorete a servi la perfecionarea metodelor de predare (evaluare, nvare) a structurilor de date de tip list liniar n liceu. Lucrarea este structurat astfel : Capitolul 1 Metodologie didactic cuprinde descrierea principiilor, obiectivelor i metodelor didactice folosite la predarea informaticii. n cadrul acestui capitol se prezint avantajele instruirii programate i nvarea asistat de calculator. Capitolul 2 Noiuni introductive conine o prezentare general a structurilor de date, definirea noiunilor de dat, structur de date, tip de structur de date, clasificri ale structurilor de date, precum i descrierea tipurilor de structuri. Capitolul 3 Metodica predrii structurii de date de tip list este partea esenial a lucrrii i prezint modalitatea de predare a listelor liniare. Se definete structura de date de tip list liniar, apoi se trateaz structura implementat static i structura implementat dinamic. Pentru fiecare din cele dou tipuri de implementri sunt descrise operaiile care se pot executa cu structura respectiv. Fiecare operaie care se poate realiza asupra listelor liniare este prezentat urmrind urmtorul ablon : Se prezint operaia care urmeaz a fi realizat; Se enumer etapele realizrii operaiei; -2-

Se prezint figura care urmrete etapele realizrii operaiei precum i efectele pe care le are aceast operaie asupra ntregii structuri de date; Funcia C care efectueaz operaia descris; Un aspect important n procesul de formare a priceperilor i deprinderilor l constituie i prezena exemplelor, exerciiilor i problemelor rezolvate; Capitolul 4 Pachetul de programe LinearList - Pachetul de programe LineaLlist ilustreaz forma listei liniare simplu nlnuit i operaiile care se pot executa cu aceasta. Aplicaia LinearList a fost realizat din dorina de a veni n sprijinul elevilor care studiaz aceast structur de date. Acest pachet de programe se poate folosi la ,,desenarea" operaiilor cu o list liniar nlnuit i are ca scop familiarizarea elevilor cu structura de tip list liniar simplu nlnuit i formarea priceperilor i deprinderilor de a realiza programe n care se utilizeaz aceast structur de date. Fiecare operaie care se poate realiza asupra elementelor unei liste liniare este prezentat amnunit, pornind de la descrierea operaiei i terminnd cu funcia C corespunztoare. Nu lipsesc nici desenele, i pentru fiecare operaie sunt prezentate : descrierea operaiei; desenul; funcia C. Paii urmrii n realizarea operaiei i funcia C sunt afiate n paralel, etap cu etap, pentru ca elevii s poat urmrii ce se ntmpl cu lista la efectuarea unei etape a operaiei respective, iar desenul ilustreaz efectul descris n etapa respectiv. Pentru exemplificarea lucrului cu liste liniare simplu nnuite am realizat i cteva exemple ce vor putea fi rulate acionnd butonul Exemple. Elevii vor putea crea propriile liste liniare i vor avea posibilitatea s realizeze asupra lor toate operaiile prezentate pe parcursul aplicaiei. Am ataat lucrrii dou anexe unde am prezentat dou proiecte didactice: Crearea listelor liniare simplu nlnuite i Operaii asupra listelor liniare simplu nlnuite. Sarcina important a profesorului de informatic este aceea c trebuie s gseasc modalitatea de a educa i instrui tnra generaie astfel nct elevii s fie capabili s-i formeze o viziune asupra lumii n mod corespunztor. Elevul i studentul de azi este ceteanul de mine. El trebuie s se pregteasc pentru a munci n societatea de mine.

-3-

1. Metodologie didactic

1.1. Principii, metode i obiective didactice

1.1.1. Principii didactice


Un model al sistemului de nvmnt trebuie s se ncadreze n contextul legilor obiective care acioneaz n societate n momentul respectiv. Coninutul, scopul, sarcinile concrete ale predrii informaticii pot fi deduse din planurile de nvmnt, precum i din alte activiti specifice (colare sau extracolare). Aceasta corespunde stadiilor de nvare fixate n conformitate cu dezvoltarea intelectual a elevilor, o atenie prioritar trebuind s fie direcionat spre adaptarea la nou, inclusiv n ceea ce privete dezvoltarea bazei materiale. Principiile didactice reprezint normele generale care orienteaz conceperea, organizarea i desfurarea procesului de predare/nvare. Unele din caracteristicile generale ale principiilor sunt : caracterul logic, ceea ce nseamn c ele exprim raporturile eseniale i globale care orienteaz conceperea i desfurarea procesului de nvmnt; caracterul obiectiv, adic se asigur o orientare a procesului de nvmnt nefalsificat i detaat de impresii, tendine i dorine subiective; procesul de nvmnt este de dorit a fi orientat n concordan cu legile dezvoltrii psihice ale individului, precum i cu legile evoluiei societii; caracterul algoritnic se exprim cerine i soluii prin utilizarea unui sistem precis de reguli, care trebuie cunoscute i respectate cu exactitate dac se dorete o orientare eficient a procesului de nvmnt; caracterul dinamic principiile didactice sunt elemente logice, dar deschise nnoirilor i creativitii. Ele trebuie s fie n pas cu schimbrile i mutaiile care pot interveni n actul didactic; caracterul sistematic fiecare principiu intr n relaie cu celelalte principii, alctuind un ansamblu unitar de legi ale crui componente se condiioneaz reciproc. Pentru o bun organizare i desfurare a procesului de nvmnt, profesorul trebuie s respecte i s aplice corect urmtoarele principii didactice : principiul intuiiei; principiul legrii teoriei de practic; principiul nsuirii contiente i active a cunotinelor; principiul sistematizrii i continuitii cunotinelor; principiul accesibilitii cunotinelor; principiul nsuirii temeinice a cunotinelor; principiul individualizrii i diferenierii nvrii.

-4-

1.1.2. Obiective didactice


Succesul oricrei activiti didactice este condiionat de claritatea i ordonarea obiectivelor pe care aceasta le urmrete. Mai mult dect n oricare alt domeniu, procesului de nvmnt informatic i este caracteristic intenionalitatea, orientarea ctre realizarea unor obiective, spre producerea unor schimbri i transformri care s poat fi controlate i dirijate. n acest spirit, cea mai important condiie pentru reuita predrii informaticii este structurarea, contientizarea i ierarhizarea unor obiective generale i specifice, adaptate particularitilor de vrst ale elevilor, coninutului cunotinelor i pregtirii lor tiinifice i metodice. Un obiectiv didactic este o descriere a unui ansamblu de comportamente i performane de care elevul trebuie s se arate capabil. Obiectivele-cadru au un grad ridicat de generalitate i complexitate i se refer la formarea unor capaciti i aptitudini specifice disciplinei i sunt urmrite pe o ntreag perioad de colarizare. Obiectivele de referin specific rezultatele ateptate ale nvrii i urmresc n special progresul realizat n acumularea de cunotine i n formarea deprinderilor, de regul pe perioada unui an de studiu. Transformrile care au loc n societate, dezvoltarea i rspndirea informaticii, ptrunderea rapid n viaa economic, social i n nvmnt a celor mai noi realizri n domeniul hardware-ului i software-ului impun o diversificare a pregtirii elevilor de liceu n acest domeniu. Pentru realizarea acestui obiectiv pedagogic, este necesar ca elevul : s dobndeasc cunotinele necesare nelegerii principalelor aspecte legate de noiunea de informaie (culegere, prelucrare, stocare, transmitere); s-i formeze i modeleze modul de gndire i abordare a problemelor; s-i formeze i s-i dezvolte deprinderi de a munci individual i n echip; s capete deprinderi care-l vor ajuta s devin un utilizator profesionist; s-i formeze o conduit i o moralitate profesional.

1.1.2.1. Clasificarea obiectivelor


Exist dou mari categorii de obiective ce trebuie avute n vedere n momentul proiectrii unei lecii : obiective sub raport stadial; obiective sub raport psiho-pedagogic.

1.1.2.1.1 Obiective sub raport stadial


Acestea sunt obiective care, la rndul lor, se pot mpri n : Obiective fundamentale (finale) definesc elementele i sarcinile rezultate din delimitarea scopului final al educaiei, cum ar fi cele legate de formarea unei personaliti puternice, complexe, cu o mare dispoziie spre iniiativ i creativitate. Avem n vedere : formarea capacitii de asimilare a cunotinelor de ctre elevi; -5-

formarea capacitii de transfer a cunotinelor i a experienei deja dobndite la rezolvarea unor sarcini necunoscute, aprute pe parcursul derulrii procesului didactic; formarea limbajului specific de profil; formarea unei atitudini tiinifice; trebuie creat un respect al elevului pentru tiin i importana acesteia n evoluia sa ulterioar; elevul trebuie s neleag c procesul de cunoatere nu se ncheie ntr-o perioad determinat de timp, c, pentru a fi eficient, procesul de cercetare trebuie s prelucreze orice informaie n mod critic, abinndu-se de la a face afirmaii categorice. Obiective intermediare sunt formulate n planul-cadru al procesului de nvmnt. n primul rnd se urmrete dobndirea unei culturi generale de baz (n nvmntul preuniversitar), a unei culturi de specialitate (n nvmntul superior) sau chiar a unei meserii (coli de profil). Obiective secveniale reprezint obiectivele specializate, orientate spre anumite laturi ale procesului de educaie: intelectual, tehnologic, profesional, moral, estetic, fizic etc. Obiective operaionale privesc ndeplinirea concret a unor activiti curente, cum ar fi cele legate de predarea unei lecii sau de exemplificarea unor teme de laborator.

1.1.2.1.2 Obiective sub raport psiho-pedagogic


Sunt obiectivele didactice necesare formrii de capaciti intelectuale (teoretice, practice) i/sau afective i se pot clasifica pe mai multe categorii: Obiective cognitive/de cunoatere. Prin acestea se urmrete formarea/ dezvoltarea urmtoarelor capaciti intelectuale : cunoaterea : posibilitatea, n principal, a ndeplinirii sarcinilor legate de memorarea, reproducerea i recunoaterea materiei de asimilat; nelegerea : se refer la transpunere, interpretare i extrapolare. 1. Transpunerea nseamn reformularea unei definiii/noiuni sau a unui rezultat cu proprile cuvinte; 2. Interpretarea nseamn nelegerea comportrii/evoluiei unui obiect/sistem dat ntr-un context clar precizat; 3. Obiectivele legate de extrapolare au drept consecin cptarea ndemnrii de a evidenia consecine noi, neidentificate nc n procesul anterior. analiza : demonstreaz capacitatea elevului de a gndi discriminativ, profund, deductiv, de a distinge faptele concrete de ipotezele de lucru; sinteza : vizeaz, n principal, activitatea intelectual de corelare logic a fenomenelor observate i a cunotinelor asimilate, n vederea realizrii unor lucrri cu caracter personal; evaluarea : implic posibilitatea formulrii de ctre elevi a unor judeci de valoare, originale, raportate la cantitatea de informaii acumulate pn n acel moment.

-6-

Obiective psihomotorii/acionale. Asemenea obiective includ formarea de priceperi, capaciti, deprinderi motorii/practice legate de utilizarea corect a ntregii aparaturi de laborator. Obiective afective. Acestea au scopul de a dezvolta emoii i sentimente superioare, contribuind la formarea contiinei i conduitei morale.

1.1.2.2. Formularea i operaionalizarea obiectivelor


n momentul n care un plan de nvmnt i program analitic sunt fixate, formularea obiectivelor este obligaia profesorului i constituie o parte indispensabil a oricrei planificri didactice generale. Operaionalizarea acestora presupune n plus faptul c un cadru didactic are o orientare global i coerent asupra ntregului proces de nvmnt, c el cunoate i aplic n mod curent elementele de metodic, c procesul n sine de coordonare a nvrii n clas nu mai are secrete. n urma oricrei lecii, elevii trebuie s dobndeasc anumite cunotine, s aib abilitatea de a le structura (analiza, sinteza) n mod creator. Acetia trebuie s aib i posibilitatea de a se manifesta direct, intervenia profesorului trebuind s fie mai degrab discret. Prin urmare, operaionalizarea nseamn transpunerea scopurilor urmrite de obiectivele formulate n termenii unor operaii, aciuni sau manifestri observabile i aflate n concordan cu cerinele generale. Obiectivele operaionale sunt imediate, putnd ns avea n anumite situaii i o finalitate pe un termen mai lung; aceasta n ideea c deprinderile i cunotinele dobndite anterior va trebui s fie completate prin aciuni viitoare care s contribuie decisiv la includerea lor n sistemul individual de informaii i ndemnri. Dac, la un moment dat se are n vedere o cantitate mai restrns de date (informaii), se va urmri definirea a cte unui obiectiv de recunoatere, de nelegere, de aplicare, de reprezentare etc. Dac aceast cantitate este mai complex, se poate aduga i un obiectiv general (de genul formare i utilitate). Operaionalizarea obiectivelor trebuie s implice, eventual gradat, etape diferite de dificultate care s precizeze : obiectivele n termeni comportamentali observabili; sarcinile concrete de nvare, precum i contextul de realizare; informaia (final) cerut de obiectiv; criteriul de succes i modul de evaluare.

1.1.3. Metode didactice


Sarcinile didactice se realizeaz cu ajutorul metodelor, tehnicilor i procedeelor didactice. Folosirea judicioas a acestora are o deosebit importan pentru reuita activitii de la catedr. Pe de alt parte, coninuturile fiecrei discipline i obiectivele pe care i le propune pretind metode specifice. Adoptarea - i nu adaptarea metodelor de predare ale unor discipline la alte discipline poate conduce la rezultate contradictorii. Aplicarea metodelor, tehnicilor i procedeelor didactice genereaz activiti de nvare specifice.

-7-

1.1.3.1. Metode generale de nvare

Trebuie s avem n vedere care dintre obiectivele operaionale sunt urmrite prin studiul disciplinelor de informatic, ce cunotine noi vor asimila elevii i ce cunotine deja dobndite n cadrul altor discipline vor fi utilizate. Informatica poate adopta i adapta metode de predare de la alte discipline, dar acest lucru trebuie s se fac inndu-se cont de : dinamica coninuturilor i particularitile metodice ale predrii disciplinei; individualizarea nvrii informaticii ca disciplin deschis i dinamic; constructivism, care pretinde o participare prioritar contient a elevului la procesul de autoinstruire; studiul informaticii att ca disciplin autonom, ct i ca instrument operaional al altor discipline. Metodele generale utilizate n predarea informaticii sunt : expunerea sistematic a cunotinelor; conversaia problematizarea; modelarea demonstrarea folosind materialul intuitiv; exerciiul; nvarea pe grupe mici; munca cu manualul; jocurile didactice; instruirea programat. Modelarea, ca i metod pedagogic, poate fi descris ca fiind un mod de lucru prin care gndirea elevului este condus la descoperirea adevrului folosindu-se un aa-numit model i utilizndu-se raionamentul prin analogie. Modelul i metoda n sine nu presupun o asemnare perfect cu cazurile iniial specificate, ci numai o analogie rezonabil. Ea const n construirea unui sistem S1 a crui descriere coincide cu descrierea sistemului original S pn la un anumit punct. S1 poate avea o natur diferit i este n general mai simplificat i formalizat. nvarea informaticii prin modelare presupune dou etape. ntr-o prim etap, nvarea se va face pe baza modelelor construite de profesori, etap n care se vor analiza trsturile modelului i compararea lui cu originalul. n a doua etap, elevii vor fi deprini s construiasc singuri modele. Importana descoperirii modelului de ctre elev const n faptul c elevul este obinuit s prezinte ntr-o form standard condiiile impuse de problem i i adncete convingerea c informatica este un domeniu n care rezultatele pozitive se obin doar printr-o nlnuire logic de raionamente. Folosirea modelelor n nvare deschide pentru informatic o impresionant arie de aplicabilitate (inclusiv utilizarea ei n predarea altor discipline, de la artele plastice la cele mai diverse domenii ale tehnicii ). Prin exemplificare sau demonstraie se nelege prezentarea sistematizat i organizat a unor obiecte, procese, experimente, cu scopul de a uura nelegerea intuitiv i executarea corect a unor activiti programate. Utilizarea intuiiei mpreun cu exemplificarea necesar poate implica folosirea a diverse modaliti i tehnici didactice datorit diversitii materialului de studiu. Exemplificarea sau demonstrarea materialului intuitiv presupune utilizarea obiectelor reale, cum ar fi : materialul grafic (plane, scheme); retroproiector/videoproiector i material pretiprit; calculator (imagini grafice, multimedia, power point). n acest context, putem spune c prin demonstrarea materialului intuitiv se -8-

nelege prezentarea sistematic i organizat a unor obiecte, procese etc. sau producerea unor experiene, fenomene n faa elevilor, cu scopul de a uura nelegerea i executarea corect a unor activiti 1. Convertirea principiului intuiiei n metoda demonstraiei se realizeaz n funcie de materialul intuitiv : machete, grafic, film didactic, televiziune colar, software-uri de nvare. Materialul intuitiv este frecvent folosit n numeroase lecii cum ar fi : nvarea algoritmilor de sortare, unde prin diferite moduri de reprezentare sunt urmrite grafic valorile care se compar i se schimb ntre ele, conducnd la ordonarea irului; nvarea metodei backtracking, unde folosind materialul natural se urmrete formarea soluiei prin avansri i ntoarceri repetate; Vizualizarea ocuprii i eliberrii zonelor de memorie prin alocarea dinamic a variabilelor; Ilustrarea modului de lucru cu elementele listelor simplu i dublu nlnuite, a stivelor i a cozilor; Echilibrarea arborilor binari (AVL). innd cont de eficiena transmiterii informaiei prin mijloacele vizuale i de orientarea cu predilecie spre mijloacele de informare rapid care solicit att memoria vizual, ct i cea auditiv i formarea involuntar a unui public consumator de informaie audio-video, o orientare a metodelor i procedeelor didactice n vederea exploatrii acestei stri de lucru creeaz un avantaj aparte procesului instructiv-educativ. Crearea unor filme didactice care s urmreasc cu exactitate programa colar creeaz faciliti de predare multor discipline i ar permite elevului s poat revizualiza predarea leciei. Aceasta ar putea elimina ambiguitile sau golurile create de momentele de neatenie din timpul predrii i ar constitui un veritabil profesor la purttor al elevului. Este evident c acest mijloc didactic nu poate nlocui exerciiul individual i nici prezena efectiv a cadrului didactic. Efortul profesorului este ns cu totul special. Nu este suficient ca un elev s vad un material, el trebuie nvat s vad. Manualele colare, purttoare ale valenelor formative prin deosebitul lor coninut metodic i didactic, reprezint o limit impus de programa colar din punctul de vedere al coninutului informativ. n informatic, mai mult dect n alte domenii, manualul este supus perisabilitii coninuturilor prin frecvena cu care disciplina este receptiv la noutile domeniului. Realitatea didactic reliefeaz faptul c elevul folosete pentru nvarea teoriei doar notiele luate n clas la predare i, din considerente de comoditate sau obinuin, foarte puini (sau deloc) manualele. Acestea sunt consultate n cel mai fericit caz doar pentru citirea enunurilor problemelor. Atitudinea de reinere sau de respingere fa de manual are consecine negative att asupra caracterului formativ, ct i asupra celui informativ al nvrii. Capacitatea de raionament a unui copil nu se formeaz numai dup modele de raionament oferite de profesor, ci i prin eforturi proprii, prin activitatea proprie de cutare i comparare cu alte scheme de raionament. Valoarea acestei metode nu const numai ntr-o nsuire temeinic a cunotinelor, ci i n formarea unor deprinderi de activitate intelectual. Metoda muncii cu manualul este un aspect al studiului individual i se introduce ca metod, treptat, sub directa ndrumare i supraveghere a profesorului. Nu orice lecie poate fi nsuit din manual. Metoda se aplic numai leciilor care au n manual o redactare sistematic i accesibil nivelurilor de vrst i de cunotine ale elevilor. Metoda poate fi aplicat pentru studiul unor aplicaii soft, limbaje procedurale (de exemplu, HTML), sau n studiul comenzilor sistemelor de operare. Elevilor li se recomand studiul temei stabilite pentru acomodarea cu noiunile, apoi profesorul reia prezentarea cu sublinierea aspectelor eseniale.
1

I. Rus, D. Varna Metodica predrii matematicii, Editura Didactic i Pedagogic, Bucureti, 1983

-9-

1.1.3.1.1. Instruirea programat i nvarea asistat de calculator

Instruirea programat poate fi aplicat cu mare succes n momentele n care obiectivul primordial al predrii l constituie utilizarea unui mecanism real. n cadrul instruirii programate, eseniale devin probele i produsele demonstrative, pe care ar trebui sa le descriem elevilor. Trebuie avut n vedere c numrul de ore afectat acestei instruiri programate s nu fie foarte mare. Acestea trebuie s includ un numr suficient de ore de verificare a cunotinelor acumulate, evitndu-se ns monotonia i instaurarea plictiselii. Trebuie evitat i folosirea metodei un timp ndelungat, lucru care poate duce n anumite situaii la o izolare social a elevului. Aceste efecte ar putea fi contracarate prin creterea numrului de ore sau prin organizarea activitilor pe grupuri sau n echip. Instruirea asistat de calculator este un concept ce difer de instruirea programat doar prin modalitatea de utilizare. Exist aceleai premise i moduri de utilizare, cu excepia faptului c un sistem de calcul devine principala interfa dintre profesor i elev. Astfel, toate noiunile, conceptele, exerciiile, problemele, evalurile, testrile, prezentrile legate de o anumit tem n cadrul unei lecii sunt ndepliniri, dirijri, verificri cu ajutorul calculatorului (mediul soft corespunztor). Procesul de predare-nvare, precum i cel de verificare-evaluare funcioneaz pe baza principiului cibernetic comand-control-reglare (autoreglare). Instruirea programat, ca metod didactic, presupune construirea unor programe de nvare care, prin fragmentarea materialului de studiat n secvene, realizeaz o adaptare a coninuturilor la posibilitile elevilor, la ritmul lor de nvare, asigur o nvare activ i o informare operativ asupra rezultatelor nvrii, necesar att elevului, pentru autocorectare, ct i profesorului. Programele informatice construite n mod deliberat pentru a putea fi utilizate n organizarea unei situaii de predare-nvare-evaluare se numesc programe educaionale sau software educaional (software didactic). n elaborarea programelor educaionale se au n vedere urmtoarele operaii: precizarea obiectivelor operaionale n funcie de coninut i posibilitile elevilor; structurarea logic a coninutului dup principiul pailor mici i al nvrii gradate; fracionarea coninutului n secvene de nvare (uniti didactice) inteligibile i nlnuite logic; fixarea dup fiecare secven a ntrebrilor, exerciiilor sau problemelor ce pot fi rezolvate pe baza secvenei informaionale nsuite; stabilirea corectitudinii rspunsurilor sau soluiilor elaborate; aceasta se poate realiza fie prin alegerea dintre mai multe rspunsuri posibile-iar n situaia n care nu s-a ales rspunsul corect, se poate recurge la ntrebri suplimentare-, fie se elaboreaz un rspuns i se compar cu cel corect. n funcie de obiective, coninuturi, activitile elevilor i evaluare, programele educaionale se pot clasifica n funcie de scopul urmrit, astfel: programe demonstrative, care permit demonstrarea unor fenomene, operaii, figuri, etc; - 10 -

programe de simulare, care permit reprezentarea controlat a unui fenomen, obiect, reacie, sistem real, prin intermediul unui model care are un comportament analog; programe de exersare. Aceste programe intervin ca supliment al leciei, temei predate, fiind destinate consolidrii unui numr limitat de deprinderi specifice unei discipline, prin seturi de sarcini repetitive, urmate ntotdeauna de aprecierea rspunsului utilizatorului; programe de testare ce asigur intervenia calculatorului n una sau mai multe etape de verificare a cunotinelor. n acest tip de instruire, calculatorul nu numai c transmite un mesaj informaional, dar el poate mijloci formarea i consolidarea unor metode de lucru, de nvare. Se poate afirma c nvarea asistat de calculator nu numai c nva elevul, dar l nva i cum s nvee. Prin aplicarea acestei metode de nvare nu se ntrevede diminuarea rolului profesorului. Dimpotriv, sarcinile lui se amplific prin faptul c va trebui s elaboreze programe i s le adapteze la cerinele procesului educativ. Orict de complete ar fi programele de nvare asistat de calculator, profesorul rmne cea mai perfecionat main de nvat.

- 11 -

2. Noiuni introductive

Este necesar ca nainte de a preda elevilor tehnicile de implementare a structurii de date de tip list liniar, s se fac o prezentare general a noiunilor de dat, tip de dat, structuri de date, tipuri de structuri. Este o lecie de transmitere de cunotine iar ca metod didactic se preteaz expunerea.

2.1. Noiunea de dat


n informatic, prin dat se desemneaz un model de reprezentare a informaiei accesibil unui anumit procesor (om, unitate central, program etc.), model cu care se poate opera pentru a obine noi informaii despre fenomenele, obiectele i procesele lumii reale. O dat care apare ca o entitate indivizibil, att n raport cu informaia pe care o reprezint, ct i n raport cu procesorul care o prelucreaz, este denumit dat elementar sau scalar. Data scalar poate fi privit, ca model de reprezentare a informaiei, la nivelul unui procesor uman (nivel logic) sau la nivelul calculatorului, ca procesor (nivel fizic). Din punct de vedere logic, o dat scalar poate fi privit ca un triplet de forma: (identificator, atribute, valori), iar din punct de vedere al reprezentrii interne (fizic), modelul corespunztor este o zon de memorie de o anumit mrime, situat la o anumit adres absolut, n care sunt memorate, n timp i ntr-o form specific, valorile acesteia. Identificatorul este un simbol (nume), care se asociaz datei, pentru a o distinge de alte date i pentru a o putea referi n procesele de prelucrare (referire prin nume). Valorile datei se pot preciza prin enumerare sau printr-o proprietate comun. Ele pot fi numere ntregi, reale, complexe, valori de adevr, iruri de caractere, iruri de bii etc. Dac pe tot parcursul procesului de prelucrare data pstreaz aceeai valoare, atunci ea este denumit dat constant sau simplu constant. n caz contrar, data se numete variabil. Pentru date constante, n general, drept identificator se utilizeaz chiar valoarea, adic o astfel de dat se autoidentific prin forma textual a valorii. Atributele precizeaz proprieti ale datei i ele determin modul n care aceasta va fi tratat n procesul de prelucrare. Dintre atributele care se pot asocia unei date, cel mai important este atributul de tip. El definete apartenena datei la o anumit clas de date, clas definit dup natura i domeniul valorilor, pentru care sunt specificate anumite operaii i creia i este specific un anumit model de reprezentare intern. n acest sens, se disting date de tip ntreg, real, complex, logic etc. n afara atributului de tip, unei date i se pot asocia i alte atribute, pentru ca astfel s se precizeze mai detaliat condiiile n care aceasta va fi utilizat n prelucrare, cum sunt: precizia reprezentrii interne, ncadrarea valorii n zona aferent, modul de alocare a memoriei pe parcursul prelucrrii (static, dinamic), valoarea iniial etc.

- 12 -

2.2. Structuri de date


De cele mai multe ori, n aplicaii, datele se prezint sub forma unor mulimi sau colecii, iar prelucrarea lor nu poate fi conceput fr o organizare corespunztoare. ntre elementele (componentele) unei colecii de date pot fi identificate sau, eventual, pot fi introduse relaii care s determine pe mulimea respectiv o anumit structur, adic un anumit mod de ordonare, astfel nct s se faciliteze prelucrarea. O colecie de date pe care sa definit o structur creia i este specific un anumit mecanism de selecie i identificare a componentelor constituie o structur de date. O structur de date este o entitate de sine stttoare, individualizabil prin nume, ale crei componente i menin proprietile (tipul). Componentele structurii pot fi individualizate i selectate prin nume (identificatori) sau prin poziia pe care o ocup n structur, n conformitate cu ordinea specificat. Dac o component poate fi selectat fr a ine seama de celelalte componente, atunci se spune c structura are acces direct (de exemplu accesul prin nume). Dac, dimpotriv, localizarea unui element se face printr-un proces de parcurgere a mai multor componente, conform cu ordine acestora (traversare), atunci structura se spune c este cu acces secvenial. Structura de date poate fi creat pentru memoria intern sau pentru un suport extern de memorie (band magnetic, disc magnetic etc.). n mod corespunztor, se vorbete de structuri interne, respectiv externe (fiiere) de date. n general, structurile externe au caracter de date permanente, de lung durat, pe cnd cele interne sunt temporare. Dac n reprezentarea structurii de date pe suportul de memorie, mpreun cu componentele acesteia, se nregistreaz date care materializeaz relaiile de ordonare, atunci se spune c structura este explicit, iar datele suplimentare, de obicei adrese, se numesc referine sau pointeri. Asupra unei structuri de date se pot efectua o mulime de operaii, care se refer la valorile elementelor i/sau la structur. Dintre acestea cele mai frecvente sunt operaiile de: a) creare: memorarea structurii de date, n forma iniial, pe suportul de memorie; b) consultare: acces la elementele structurii pentru prelucrarea valorilor acestora; c) actualizare: schimbarea strii structurii prin adugarea (inserarea) unor noi elemente, tergerea elementelor care nu mai sunt necesare i modificarea valorii unor elemente; d) sortare: aranjarea elementelor structurii dup anumite date de valorile acestora; e) ventilare: desfacerea unei structuri n dou sau mai multe structuri; f) fuzionare: combinarea a dou sau mai multe structuri la fel ordonate ntr-o singur structur; g) copiere: realizarea unei copii a unei structuri, n general pe un alt suport. Operaiile la care poate fi supus o structur de date i eficiena cu care acestea pot fi realizate depind, n mare msur, de natura relaiilor de ordonare i de modul n care acestea sunt materializate pe suportul de memorie. Din acest punct de vedere, operaiile constituie un element distinctiv (proprietate) pentru diversele structuri de date. Toate structurile de date care au aceeai organizare i sunt supuse acelorai operaii formeaz un anumit tip de structur de date. n acest sens, se vorbete de structur de tip list, arbore etc., extinznd noiunea de tip de dat i asupra mulimilor ordonate de date. Analiznd modul de realizare a operaiilor pentru diferite tipuri de structuri, se poate pune n eviden faptul c acestea pot fi reduse la utilizarea, eventual repetat, a unui grup specific de operatori (funcii). Astfel, se poate spune c un tip de structur de date este o mulime ordonat de date, pe care s-a definit un grup de operatori de baz, cu o anumit semantic. Componentele unei structuri de date pot s fie date elementare sau s fie ele nsele structuri de date. n cazul n care componentele sunt de acelai tip, atunci structura este - 13 -

omogen. Tipul componentelor se numete tip de baz. Numrul valorilor distincte aparinnd unui anumit tip T se numete cardinalitatea lui T. De regul, acesta reprezint o msur a cantitii de memorie necesare reprezentrii unei variabile v de tipul T. Dac un tip de structur de date se compune din (sau se poate descompune n) structuri de date aparinnd aceluiai tip, atunci se spune c structura de date este recursiv. Operaiile aplicate asupra unei structuri de date pot s i afecteze valorile i/sau structura. Dac o structur de date i modific structura, atunci este considerat dinamic. O structur dinamic ocup n memoria intern o zon care se aloc n timpul execuiei programului, pe msura nevoii de prelucrare. Structurile dinamice pot avea un numr, teoretic nelimitat, de componente i de aceea se mai numesc i structuri cu cardinalitate infinit. Opusul structurilor dinamice sunt structurile statice, care pe tot parcursul existenei lor au acelai numr de componente i n aceeai ordine. Structurile dinamice ocup n memorie o zon de dimensiune constant, n care elementele componente ocup tot timpul execuiei programului acelai loc. Dac o structur de date ocup o zon de dimensiune constant, dar elementele componente ocup un loc variabil n timpul execuiei programului, atunci o astfel de structur se numete semistatic. Alocarea de memorie fcut de un translator pentru o structur static este o alocare static att la nivelul ntregii structuri, ct i pentru fiecare component n parte. Pentru o structur semistatic, alocarea este static la nivelul structurii i dinamic la nivelul componentelor, iar pentru o structur dinamic, alocarea este dinamic att la nivelul componentelor ct i la nivelul ntregii structuri. Trebuie subliniat faptul c aceast clasificare a structurilor de date n structuri statice, semistatice i dinamice se refer la structurile fizice de date, adic la implementrile concrete ale structurilor logice de date i nicidecum la aceste structuri. Prin aceasta se evideniaz c aceeai structur logic de date poate fi n general implementat i ca structur semistatic, respectiv ca structur dinamic. Exist totui i structuri logice de date care nu pot fi statice, cum este de exemplu stiva, care nu poate fi conceput fr operaiile de adugare, respectiv de eliminare de elemente, ceea ce i confer un caracter dinamic. Astfel de structuri pot fi implementate fie ca structuri semistatice, fie ca structuri dinamice. n concluzie, realizarea structurilor de date este dependent de scopul urmrit, exprimat prin operaiile de prelucrare la care vor fi supuse datele. Ea trebuie, pe de o parte, s defineasc structura de date din punct de vedere logic (modul de ordonare, operatori de tratare), iar pe de alt parte, s indice modul n care aceasta va fi implementat fizic (reprezentare pe suport). Definirea logic i fizic nu sunt complet separate, ci ele se condiioneaz reciproc. Practica demonstreaz c o definire logic bine realizat mrete considerabil ansele unei implementri fizice eficiente.

- 14 -

2.3. Tipuri de structuri


Definirea structurilor de date se bazeaz, n majoritatea aplicaiilor, pe structuri liniare i arborescente. Prin combinarea convenabil a acestor structuri, se pot construi structuri orict de complicate. n mod corespunztor, o mulime cu o astfel de structur este denumit structur liniar, respectiv structur arborescent de date. Structurile liniare i arborescente sunt relaii binare de ordine, cu anumite proprietti, care, n modul cel mai general, pot fi interpretate ca relaii de succesiune i se pot reprezenta sub forma unor grafuri. Fie D o mulime de date, finit, i fie R o relaie binar tranzitiv pe D. Dac a,bD i (a,b)R, atunci se spune c a precede pe b, b succede lui a sau c a este predecesor lui b, respectiv c b este succesor al lui a. De asemenea, se consider c perechea (a,b) definete un arc cu originea n a i extremitatea n b, iar despre a i b se spune c sunt noduri. Avnd n vedere relaia R, se pot pune n eviden urmtoarele submulimi ale lui D: V(D) - mulimea elementelor maximale (iniiale) ale lui D n raport cu R, definit ca: V(D) = {aD | bD, (b,a)R a=b} T(D) - mulimea elementelor minimale (terminale) ale lui D n raport cu R i care este: T(D) = {aD | bD, (a,b)R a=b} Pred(a) - mulimea predecesorilor lui aD-V(D): Pred(a) = {bD | (b,a)R} Predi(a) - mulimea predecesorilor imediai ai lui aD-V(D): Predi(a) = {bD | {v D | (b,v)R, (v,a)R = {b,a}} Su(a) - mulimea succesorilor lui aD-T(D): Su(a) = {bD | (a,b)R} Sui(a) - mulimea succesorilor imediai ai lui aD-T(D): Sui(a) = {bD | {uD | (a,u)R, (u,b)R} = {a,b}} O relaie binar R pe D este o structur liniar pe D dac R este o relaie de ordine total. Dac R este o structur liniar pe D, atunci: - card(V(D)) = card(T(D)) = l, adic exist un element unic rD, numit prim element, respectiv un element minimal unic fD, numit ultim element; - aD-T(D) > card(Sui(a)) = l, adic orice element neterminal are un succesor imediat unic; - aD-V(D) > card(Pred(a)) = l, adic orice element diferit de r are un predecesor imediat unic; - r,fD > Predi(r) = Sui(f)) = , adic primul element nu are predecesori i ultimul element nu are succesori. Pentru o structur liniar R pe D poate fi considerat i relaia invers R-1 care de asemenea este o structur liniar pe D. Dac ntr-o structur liniar R, se consider c i (f,r)R, atunci se spune c structura este inelar sau circular. De remarcat, de asemenea, c pentru orice aD, mulimea {a}Su(a) posed o structur liniar indus de R, ceea ce arat natura recursiv a structurii. - 15 -

Convenind s marcm nodurile prin puncte i arcele prin sgei (sgei punctate pentru R1 ), structurile liniare pot fi redate grafic ca n Fig. 1.3.1.3.

Fig. 1.2.3. Structuri liniare i circulare

2.4. Alocare dinamic. Pointeri


Aceast lecie are scopul de a familiariza elevii cu modul de alocare a memoriei i este o introducere la lecia de predare a structurii de date de tip list liniar. Se vor prezenta elevilor diferenele dintre lucrul cu pointeri i lucrul cu tablouri, punndu-se n eviden avantajele i dezavantajele fiecrei tehnici. La sfritul leciei elevii vor trebui s fie capabili s enumere diferenele dintre variabilele locale i variabilele dinamice i s neleag lucrul cu pointeri. Dup transmiterea noilor cunotine, este bine s se rezolve ct mai multe exerciii prin care s se evidenieze cele mai frecvente erori care apar n programele n care se utilizeaz variabile dinamice. Ca i metode didactice se recomand utilizarea conversaiei i a exerciiului. O variabil este un obiect (zon de memorie identificabil ) care poate pstra una sau mai multe valori (la momente succesive din execuia programului). Se caracterizeaz prin: identificator (mijlocul prin care se fac referiri la ea n textul surs); spaiul de memorie necesar/rezervat; clasa de memorare; vizibilitate; durata de viat; linkage. - 16 -

Prin locaie de memorie vom nelege cea mai mic unitate de memorie adresabil. De obicei, unitatea minim de memorie adresabil este byte-ul. Locaiile de memorie sunt consecutive i numrul lor de ordine (numr ntreg pozitiv) reprezint adresa lor . Exist o strns legatur ntre dimensiunea memoriei adresabile i numrul de bii pe care se reprezint adresele locaiilor de memorie. Informaiile memorate de un calculator (fie ele date sau coduri de instruciuni sau chiar adrese) pot ocupa una sau mai multe locaii succesive de memorie. Indiferent nsa cte locaii de memorie ocup o informaie ce trebuie stocat, adresa de nceput a grupului de locaii ocupate este o adres. Altfel spus, informaiile de tip adres ocup acelai numr de octei, indiferent de tipul informaiei stocate ncepnd cu acea adres. De obicei adresele se reprezint pe doi sau patru octei. Domeniul unei variabile reprezint poriunea din textul surs n care identificatorul variabilei poate fi utilizat legal. Prin clas de memorare se specific locul n care se creaz variabila (zona de date statice, stiva sau registru) i daca se iniializeaz implicit (numai variabilele cu clasa de memorare static) sau nu. Vizibilitatea unei variabile este poriunea din domeniul variabilei peste care nu se suprapune domeniul altei variabile de acelai tip i cu acelai nume Durata de via a unei variabile o reprezint perioada din timpul de execuie al unui program n care variabila continu s existe (i pstreaz valoarea) fie c poate sau nu s fie accesat. O variabila local (stack) este declarat sub un anumit nume prin intermediul cruia va fi referit n cadrul blocului n care a fost declarat, alocndu-i-se memorie la activarea blocului. Variabila va exista (va ocupa memoria alocat ei) atta timp ct blocul n care a fost declarat este activ. n limbajul C, alocarea dinamic se realizeaz prin diversele variante ale funciei malloc(), iar eliberarea zonelor alocate se face prin funcia mfree(). Adresa zonei de memorie alocat unei variabile dinamice va fi depus ntr-o variabil de tip special, numit pointer. Variabilele dinamice se aloc dinamic ntr-o zon special numit HEAP i se distrug la cererea programatorului. Neavnd nume, variabilele dinamice trebuie referite prin intermediul altor variabile, numite din acest motiv variabile pointer (Fig. 1.3.2.).

Fig 1.3.2. p este un pointer la o variabil de tip char Pointerii sunt variabile a cror valoare este interpretat ca adres a unei locaii de memorie unde poate fi accesat o valoare de tipul declarat al pointerului. La fel ca n cazul oricror variabile, variabilele pointer globale sau cele locale declarate static se iniializeaz automat, cu valoarea NULL. NULL, ca valoare a unui pointer, este o adres invalid. Ea se folosete doar pentru a indica faptul c pointerul care are valoarea respectiv nu poate fi utilizat ntr-o operaie de derefereniere. Ca mod de reprezentare, valorile variabilelor pointer sunt numere ntregi far semn i necesit un spaiu echivalent cu spaiul necesar reprezentrii adreselor n sistemul de operare/main gazd a compilatorului. Chiar dac un pointer declarat local ntr-o funcie este iniializat via malloc, este necesar apelul funciei free cu acel pointer ca argument pentru c spaiul alocat dinamic este gestionat printr-un alt mecanism dect cel rezervat pentru variabilele locale. n absena apelului free, zona respectiv de memorie nu va mai putea fi alocat ulterior, n cursul execuiei curente a programului. - 17 -

Ca lecie introductiv la lecia de predare a structurii de date de tip list liniar, se va face o prezentare general a tablourilor i a pointer-ilor cu punerea n eviden a punctelor forte i a celor slabe pentru fiecare tip de dat. Este foarte important ca elevii s poat decide n diferite contexte ce vor folosi : pointeri sau tablouri, n funcie de cerinele problemei, motiv pentru care li se vor prezenta avantajele i dezavantajele lucrului cu pointeri, respectiv cele ale utilizrii tablourilor. Ca metode didactice se recomand folosirea conversaiei i a exerciiului. Pointerii, dei contribuie la scderea lizibilitii programelor C, reprezint n anumite situaii o alternativ mult mai eficient dect utilizarea tablourilor. Pe de o parte utilizarea pointerilor poate micora semnificativ timpul de acces la elementele unui tablou iar pe de alt parte, utilizarea pointerilor reprezint singura modalitate de acces la zone de memorie alocate dinamic (n timpul execuiei). Tablourile sunt probabil cea mai cunoscut i utilizat structur de date folosit pentru memorarea coleciilor de elemente. Sunt uor de declarat i ofer sintaxa [] pentru accesul la oricare element prin intermediul indexului su. Exemplul urmtor prezint iniializarea elementelor unui tablou i modul cum se aloc spaiu n memorie. Se declar un tablou de tipul ntreg, primele trei elemente sunt iniializate cu numerele 1, 2 respectiv 3, i las restul irului neiniializat.
void TestTablou() { int tablou [100]; tablou [0]=1; tablou [1]=2; tablou [2]=3; ... }

Figura 2.3.2. prezint felul cum va arta tabloul tablou n memorie. Cel mai important este faptul c ntregul tablou este alocat ca un singur bloc de memorie. Fiecare element din tablou are propriul spaiu i fiecare element poate fi accesat direct folosind sintaxa []. tablou 1 Index 0 1 2 2 3 -3451 3 23142 99

2.3.2. Reprezentarea tabloului n memoria calculatorului. Dezavantajele lucrului cu tablouri sunt : 1. dimensiunea tabloului este fix 100 de elemente n acest caz. Cel mai des, dimensiunea este specificat la momentul compilrii, cu o declaraie simpl, ca cea din exemplu. Cu puin efort, dimensiunea tabloului poate fi modificat pn n momentul cnd tabloul este creat la momentul rulrii, dar dup aceea rmne fix.1 2. datorit primului punct, cea mai bun soluie pentru programatori este s aloce spaiu suficient de mare. Totui, aceast strategie are dou dezavantaje : a. de cele mai multe ori sunt doar 20, 30 de elemente n tablou i 70% din spaiu este irosit;

folosindu-ne de alocarea dinamic a tablourilor n HEAP, se poate redimensiona tabloul utiliznd realloc()

- 18 -

b. dac programul necesit mai mult de 100 de elemente, ca n exemplu, programul eueaz. O foarte mare cantitate de soft-uri comerciale folosesc acest tip de tablouri care irosesc spaiul, iar uneori eueaz.2 3. un dezavantaj minor este acela c inserarea unui nou element la nceput este costisitor deoarece elementele existente trebuie deplasate pentru a face loc celui nou. Listele nlnuite au i ele propriile puncte forte i puncte slabe, dar sunt eficiente acolo unde tablourile sunt slabe. n cazul tablourilor toate elementele sunt alocate ntr-un singur bloc de memorie. Listele nlnuite folosesc o cu totul alt strategie : aloc memorie separat pentru fiecare element i doar atunci cnd este necesar. Elevii trebuie s identifice corect cazurile cnd n probleme este necesar folosirea tablourilor sau a listelor. Tipurile de probleme care presupun luarea unei decizii asupra metodei care trebuie folosit sunt : 1. Se cunoate dimensiunea tabloului (volumul de date) la momentul elaborrii programului. Soluie: folosirea unui tablou cu dimensiunea fix n fiierul surs (eventual n fiierul surs sau ntr-un fiier header se definete cu directiva define dimensiunea tabloului, astfel nct dac se dorete o versiune a aplicaiei care s permit un volum diferit de date se modific definiia). 2. Se cunoate volumul de date abia la nceputul execuiei programului (pentru fiecare execuie volumul de date este posibil s difere). Soluie: folosirea unui tablou pentru care se aloc spaiu n mod dinamic i accesul la elementele tabloului se va face de regul prin pointeri. 3. Volumul de date nu se cunoate nici mcar la nceputul execuiei ci doar la sfritul fazei de creare/citire a datelor. Soluie: datele se vor implementa sub form de list.

pentru tablouri de dimensiuni mari (mai mari de 8k bytes ), memoria virtual a sistemului poate compensa parial aceast problem, din moment ce elementele irosite nu sunt utilizate.

- 19 -

3. Didactica predrii structurii de date de tip list

Lecia de predare a structurii de date de tip list liniar se va ntinde pe parcursul a mai multor ore de curs i pentru desfurarea activitii de predare ntr-un cadru adecvat prezentrii acestui tip de structur de dat, profesorul va dispune de plane, fie, folii pentru retroproiector sau pe calculatoare. De asemenea se folosesc desene pe tabl care vor nsoi prezentarea fiecrei operaii care se poate realiza cu listele liniare.

3.1. Tehnici de implementare a listelor

Lista este o multimulime dinamic, adic o colecie cu un numr variabil de elemente, care se pot repeta. Elementele sunt de acelai tip. Elementele unei liste se numesc noduri. Dac ntre nodurile unei liste exist o singur relaie de ordine, atunci lista se numete simplu nlnuit. Dac ntre nodurile unei liste exist dou relaii de ordine, atunci lista se numete dublu nlnuit. n general, vom spune c o list este n-nlnuit dac ntre nodurile ei sunt definite n relaii de ordine. O caracteristic esenial a structurii de date de tip list este poziia relativ liniar a elementelor listei. n legtur cu listele, se au n vedere unele operaii de interes general : crearea unei liste; accesul la un nod oarecare al listei; inserarea unui nod ntr-o list; tergerea unui nod dintr-o list; tergerea unei liste. Pentru structurile de date fundamentale exist construcii de limbaj ce le reprezint, construcii care i gsesc un anumit corespondent n particularitiile hardware ale sistemelor care le implementeaz. Pentru structurile de date avansate ns, care se caracterizeaz printr-un nivel nalt de abstracie, acest lucru nu mai este valabil. De regul reprezentarea acestor structuri se realizeaz cu ajutorul structurilor de date fundamentale.

3.1.1. Implementarea listelor prin intermediul tipului tablou

Unitatea de nvare : Structuri de date de tip list liniar implementat prin intermediul tipului tablou. Detalieri de coninut : Abordarea leciei presupune cunoaterea de ctre elevi a lucrului cu tablouri. Tipul leciei : mixt (verificare i comunicare de cunotine). Obiective operaionale : La sfritul acestei lecii elevii vor fi capabili s : - 20 -

poat defini o structur de date de tip list liniar implementat cu tipul tablou. cunoasc i s foloseasc n aplicaii principalele operaii care se pot efectua cu elementele unei liste liniare implementat cu tipul tablou. identifice situaiile n care este recomandabil utilizarea acestei structuri de date. foloseasc n mod optim n aplicaii liste liniare astfel implementate. Metode i procedee didactice : conversaia frontal i individual, explicaia, metoda analitic, munca independent, nvarea prin descoperire, problematizarea etc. Mijloace didactice : manualul, culegeri de probleme, tabla, calculatorul, retro(video)proiectorul. Momentele leciei : Momentul organizatoric : maxim 2 minute, obiectivele urmrite fiind, desigur, crearea unei atmosfere specifice bunei desfurri a activitii didactice care urmeaz. Verificarea temei pentru acas i a cunotinelor dobndite anterior : maxim 8 minute. Captarea ateniei, prezentarea titlului i a obiectivelor leciei noi : maxim 2 minute. Activitatea profesorului se poate prezenta sub forma : a) Se prezint o situaie-problem prin care se urmrete scoaterea n eviden a importanei utilizrii unei structuri de date de tip list liniar simplu nlnuit, insistndu-se asupra avantajelor pe care le prezint aceast structur n condiiile impuse de problem. b) Se subliniaz gama de probleme care vor putea fi soluionate elegant folosind structura de date de tip list implementat prin tipul tablou. n ceea ce privete activitatea elevului, acesta ascult i noteaz cele prezentate de ctre profesor i pune ntrebri care s poat lmuri contextul n care se va desfura lecia. Prezentarea noilor coninuturi : durata estimat poate fi de 12 minute. Profesorul poate prezenta succesiv : definirea structurii de date ca un articol cu dou cmpuri; operaiile care se pot face cu elementele unei liste liniare implementat prin tipul tablou : adugarea de noduri la sfritul unei liste (se scoate n eviden cazul cnd lista este vid, cazul cnd mai exist noduri n list, precum i cazul cnd nu mai este spaiu pentru adugarea unui nou element), modificarea unui nod identificat prin informaia de nod (se scoate n eviden cazul cnd nodul de modificat nu a fost gsit sau lista este vid), tergerea unui nod identificat prin poziia din list (se scoate n eviden cazul cnd poziia nodului de ters este dup ultimul element din list i cazul cnd lista este vid), inserarea unui nod n list pe o anumit poziie (se va scoate n eviden cazul lista este vid sau poziia pe care se dorete inserarea este dup ultimul nod din list), parcurgerea (afiarea coninutului) unei liste liniare (se va scoate n eviden cazul cnd lista este vid); modul de recunoatere a anumitor instane care uureaz implementarea (pstrarea sfritului listei pentru a facilita adugrile). Observaie : prezentarea operaiilor asupra nodurilor unei liste liniare implementat cu tipul tablou va fi nsoit de scheme i desene sugestive. Asigurarea conexiunii inverse (feedback) : durata estimativ este de 4 minute. Profesorul poate solicita elevilor prezentarea unor situaii problem, similare cu cele menionate anterior i pentru rezolvarea crora se poate folosi o list liniar. Se va cere i s argumenteze exemplele date. Elevii vor identifica asemenea probleme i vor propune soluii n care se va folosi structura de date nvat, prezentndu-se avantajele unei asemenea implementri. - 21 -

Prezentarea temei pentru acas : durata estimat este de 2 minute. Profesorul propune tema pentru acas, iar elevul noteaz problema propus spre rezolvare i indicaiile de implementare ale profesorului i cere eventuale lmuriri suplimentare. Dup lecia de prezentare general a structurii de date de tip list liniar implementat prin tipul tablou, urmtoarele lecii vor prezenta detaliat toate aceste operaii iar n cadrul orelor de laborator se vor propune spre rezolvare aplicaii care s ilustreze modul de folosire a structurii de date nou nvate. n implementarea listelor prin intermediul tipului tablou o list se asimileaz cu un tablou, nodurile listei fiind memorate ntr-o zon contigu de memorie, n locaii succesive. n cazul implementrii cu ajutorul tipului tablou, tipul lista se definete ca un articol cu dou cmpuri : - primul cmp este un tablou de elemente info de tip structura a crui lungime este astfel aleas de programator nct s fie suficient pentru a putea pstra cea mai mare dimensiune de list care poate s apar n respectiva aplicaie; - al doilea cmp este un ntreg ultim care indic n tablou poziia ultimului element al listei.
#define LUNG_MAX 100 typedef struct { int info[LUNG_MAX]; int ultim; }liste;

Primul nod Al doilea nod


Lista

ultim Ultimul nod Gol

Fig 1.3.1.1. Reprezentarea listelor cu ajutorul tipului tablou

n aceast reprezentare o list poate fi uor de traversat iar nodurile pot fi adugate n mod simplu la sfritul listei. Secvena urmtoare prezint listarea elementelor unei liste. Dac ultim a rmas n poziia 0, nseamn c nu a fost introdus nici un element, adic lista este vid. Altfel, se va traversa lista i se va afia fiecare element al su. - 22 -

void listare(void) { int i; if(l.ultim == -1) { printf("Lista este vida!\n"); return; } printf("\nElementele listei sunt : "); for(i=0; i <= l.ultim; i++) printf("%d", l.elemente[i]); }

Inseria unui nod n mijlocul listei presupune ns deplasarea tuturor nodurilor urmtoare cu o poziie spre sfritul listei pentru a face loc noului nod. Utilizatorul va trebui s spun poziia pe care va dori inserarea noului nod. Dac acest poziie este mai mare dect poziia indicat de ultimul element, se va semnala eroare, altfel se va face inserarea noului element. Urmtoarea secven de cod prezint inserarea unui element n interiorul listei :
Void inserare_nod_in() { printf("Introduceti pozitia unde inseram elementul:"); scanf("%u", &poz); if(poz > l.ultim) { printf("Eroare! Pozitie dupa ultimul element!\n"); return; } printf("Introduceti valoarea ce trebuie adaugata : "); scanf("%d", &val); for(i=l.ultim; i >= poz; i--) l.elemente[i+1] = l.elemente[i]; l.elemente[poz] = val; l.ultim++; }

Cutarea unui element ntr-o list se realizeaz astfel: se introduce valoarea elementului pe care dorim s-l cutm i se parcurge lista pn n momentul cnd am gsit elementul i se afieaz poziia pe care a fost gsit. Dac elementul nu a fost gsit, se va afia acest lucru. Secvena care realizeaz parcurgerea elementelor listei pentru cutarea unui anumit element este urmtoarea :
for(i=0; i <= l.ultim; i++) if(l.elemente[i] == val) { printf("Am gasit val \"%d\" pe poz \"%d\" \n",val, i); }

Suprimarea oricrui nod cu excepia ultimului presupune deplasarea celorlalte n vederea eliminrii spaiului creat. Dac se cunoate poziia nodului pe care dorim s l suprimm, secvena care realizeaz aceast operaie este urmtoarea :
for(i=poz; i < l.ultim; i++)

- 23 -

l.elemente[i] = l.elemente[i+1]; l.ultim--;

Se vor face urmtoarele observaii : 1. Dac se dorete inseria unui nod ntr-o list care deja a utilizat n intregime tabloul asociat se va semnala eroare. 2. Dac n cadrul procesului de cutare nu se gsete elementul cutat se va semnala acest lucru. Dup ce a fost prezentat maniera n care se implementeaz listele liniare simplu nlnuite cu ajutorul tipului tablou, va urma o lecie de fixare de cunotine. Metoda didactic ce va fi folosit este metoda exerciiului. Elevilor li se va cere s implementeze un algoritm n C care s efectueze asupra unei liste liniare operaiile de : - creare (crearea primului element),ce va fi realizat de funcia cu acelai nume. Crearea listei se face prin apeluri successive ale funciei inserare(); - inserare (n interiorul i la sfaritul listei) unui element, care va fi realizat de funcia inser_nod(); - cutare, care este realizat de funcia caut_nod(); - tergerea (n interiorul i la sfaritul listei) unui element este realizat de funcia delete_nod(); - listarea elementelor listei este realizat de funcia cu acelai nume; - listarea unui element de pe o anumit pozitie, care va fi realizat de funcia afiseaza_nod(). n interiorul funciei meniu(), prin intermediul unei variabile de tip caracter, utilizatorul va preciza ce operaii dorete s realizeze asupra listei. Pentru realizarea acestui program, elevii vor fi mprii pe grupe de trei, respectiv patru elevi, fiecare grup urmnd s realizeze cte o operaie. La sfritul orei cte un reprezentant din fiecare grup va scrie la tabl funcia care realizeaz operaia ce a avut-o de realizat grupa respectiv.

Grupa 1 crearea listei Aceast operaie se realizeaz prin apeluri succesive ale funciei inserare() . Se va crea primul element al listei, apoi, dac utilizatorul dorete, se vor aduga i alte elemente n list.

void creare_lista(void) { char c; do { inserare(); printf("Continuati(D/N) : "); fflush(stdin); scanf("%c", &c); c=toupper(c); } while(c=='D'); }

Grupa 2 inserarea unui element Dac mai exist spaiu n list pentru a

void inserare(void) { if(l.ultim > LUNG_MAX) {

- 24 -

printf("Nu mai exista spatiu aduga noi elemente, se cere valoarea care in lista pentru a adauga noi trebuie adugat, aceasta este introdus pe elemente!\n"); ultima poziie (indicat de ultim), apoi ultim return; este modificat astfel nct s indice prima } printf("Introduceti valoarea ce poziie liber din tablou. trebuie adaugata : "); fflush(stdin); scanf("%d", &l.elemente[l.ultim]); printf("Valoarea \"%d\" a fost adaugata in lista\n", l.elemente[l.ultim]); l.ultim++; }

Grupa 3 -Inserarea unui nod n list Inserarea unui nod se poate face la sfritul listei sau n interiorul acesteia. Succesiunea operaiilor este urmtoarea : - se verific dac mai exist spaiu pentru introducerea unui element; - se cere opiunea utilizatorului : inserarea unui element la sfritul sau n interiorul listei; - dac se dorete inserarea unui element n interiorul listei, se cere poziia pe care inserm. Dac aceasta este dup ultimul element, se semnaleaz eroare. Altfel, se va cere introducerea valorii de inserat (val) i se vor deplasa toate elementele ncepnd de la acea poziie (poz) cu o poziie spre dreapta pentru a face loc noului element. - Dac se dorete inserarea unui elment la sfritul listei se va apela funcia inserare() care va realiza aceast operaie.

void inser_nod(void) { int poz, val, i; char c; if(l.ultim >= LUNG_MAX) { printf("Nu mai exista spatiu pentru a insera un nou element in lista!\n"); return; } printf("1.Inseram un element pe o anumita pozitie\n"); printf("2.Inseram un element la sfarsit\n"); printf("Introduceti optiunea : "); fflush(stdin); scanf("%c", &c); if(c=='1') { printf("Introduceti pozitia unde sa inseram elementul in cadrul listei : "); scanf("%u", &poz); if(poz > l.ultim) { printf("Eroare! Pozitie dupa ultimul element!\n"); return; } printf("Introduceti valoarea ce trebuie adaugata : "); scanf("%d", &val); for(i=l.ultim; i >= poz; i--){ l.elemente[i+1]=l.elemente[i]; l.elemente[poz] = val; l.ultim++; } else if(c=='2') inserare(); else printf("Comanda invalida!\n");

} - 25 -

Grupa 4 listarea elementelor listei Dac lista este vid se va semnala acest lucru. Altfel, se parcurge lista element cu element i se afieaz valorile elementelor listei.

void listare(void) { int i; if(l.ultim == 0) { printf("Lista vida!\n"); return; } printf("\nElementele listei sunt: "); printf("L = ("); for(i=0; i < l.ultim; i++) printf("%d%s", l.elemente[i], ((i < l.ultim-1)?", ":")\n") ); }

void delete_nod(void) Grupa 5 suprimarea unui nod din list { Dac lista este vid se va semnala acest int poz, i; lucru. Altfel, se va cere poziia elementului de if(l.ultim == 0) { ters. printf("Lista este vida!\n"); Dac respectiva poziie este valid (este mai return; mic dect poziia indicat de ultim), } aceast operaie presupune deplasarea printf("Introduceti pozitia celorlalte n vederea eliminrii spaiului nodului din lista : "); scanf("%d", &poz); creat. if(poz < 0 || poz >= l.ultim) { printf("Pozitie invalida!\n"); return; } for(i=poz; i < l.ultim; i++) l.elemente[i] = l.elemente[i+1]; printf("Elementul de pe pozitia \"%d\" a fost sters\n", poz); l.ultim--; } void cauta_nod(void) { int val, i; if(l.ultim == 0) { printf("Lista este vida!\n"); return; } printf("Introduceti valoare nodului ce trebuie cautat : "); scanf("%d", &val); for(i=0; i < l.ultim; i++) if(l.elemente[i] == val) { printf("Am gasit valoarea \"%d\" pe pozitia \"%d\" in lista.\n", val, i); return; }

Grupa 6 cutarea unui nod n list Dac lista este vid se va semnala acest lucru. Altfel, se cere valoarea nodului ce trebuie cutat. Se parcurge lista element cu element i se verific valoarea fiecrui element cu valoarea introdus. Dac s-a gsit un element cu aceeai valoare, se afieaz poziia elementului. Altfel, se va semnala c nu exist nici un nod n list cu valoarea introdus de utilizator.

- 26 -

printf("Nu exista nici un nod in lista cu valoarea \"%d\"\n", val); }

Grupa 7 - listarea unui element de pe o void afiseaza_nod(void) { anumit pozitie int poz; Dac lista este vid se va semnala acest lucru. if(l.ultim == 0) { Altfel se cere introducerea poziiei printf("Lista este vida!\n"); elementului pe care dorim s-l vizualizm. return; Dac poziia este valid, se va afia } valoarea elementului. Altfel se va semnala printf("Introduceti pozitia eroare. nodului in cadrul listei : ");
scanf("%d", &poz); if(poz >= l.ultim || poz < 0) { printf("Pozitie inexistenta!\n"); return; } printf("Valoarea elementului de pe pozitia \"%d\" din cadrul listei este : ", l.elemente[poz]); }

Dup ce a fost scris la tabl programul i a fost verificat de ctre profesor, la urmtoarea or de laborator li se va cere elevilor s verifice execuia programului pe calculator. Acetia vor trebui s adauge funcia meniu() care va oferi utilizatorului posibilitatea s aleag operaia pe care dorete s o realizeze asupra listei i funcia main(). Se vor pstra grupele formate la ora de curs i se va putea realiza un concurs ntre grupe.

3.1.2. Implementarea listelor cu ajutorul tipului pointer

Unitatea de nvare : Structuri de date de tip list liniar simplu nlnuit alocat dinamic. Detalieri de coninut : Abordarea leciei presupune cunoaterea de catre elevi a alocrii dinamice a variabilelor, alocarea i eliberarea efectiv a zonelor de memorie aferente, lucrul cu tipul pointer i tipul struct, deosebirea dintre variabilele de tip pointer i variabilele statice. Tipul leciei : mixt (verificare i comunicare de cunotine). Obiective operaionale : La sfritul acestei lecii elevii vor fi capabili s : poat defini o structur de date de tip list liniar simplu nlnuit. cunoasc i s foloseasc n aplicaii principalele operaii care se pot efectua cu nodurile (elementele) unei liste liniare simplu nlnuite. identifice situaiile n care este recomandabil utilizarea acestei structuri de date. foloseasc n mod optim n aplicaii liste liniare simplu nlnuite. - 27 -

Metode i procedee didactice : conversaia frontal i individual, explicaia, metoda analitic, munca independent, nvarea prin descoperire, problematizarea etc. Mijloace didactice : manualul, culegeri de probleme, tabla, calculatorul, retro(video)proiectorul. Momentele leciei : Momentul organizatoric : maxim 2 minute, obiectivele urmrite fiind crearea unei atmosfere specifice bunei desfurri a activitii didactice care urmeaz. Verificarea temei pentru acas i a cunotinelor dobndite anterior : maxim 8 minute. Captarea ateniei, prezentarea titlului i a obiectivelor leciei noi : maxim 2 minute. Activitatea profesorului se poate prezenta sub forma : a) Se prezint o situaie-problem prin care se urmrete scoaterea n eviden a importanei utilizrii unei structuri de date de tip list simplu nlnuit, insistnduse asupra avantajelor pe care le prezint aceast structur n condiiile impuse de problem. b) Se subliniaz gama larg de probleme (gestionarea documentelor i reprezentrile/vizualizrile acestora n cadrul unei aplicaii concrete, gestionarea spaiului de memorie liber i/sau alocat explicit etc.) care vor putea fi soluionate elegant folosind structura de date de tip list. n ceea ce privete activitatea elevului, acesta ascult i noteaz cele prezentate de ctre profesor i pune ntrebri care s poat lmuri contextul n care se va desfura lecia.. Prezentarea noilor coninuturi : durata estimat poate fi de 12 minute. Profesorul poate prezenta succesiv : - definirea structurii de date ca o structura recursiva; - operaiile care se pot realiza cu nodurile unei liste liniare simplu nlnuite : adugarea de noduri la sfritul unei liste (se scoate n eviden cazul cnd lista este vid i cazul cnd mai exist noduri n list), modificarea unui nod identificat prin informaia de nod (se scoate n eviden cazul cnd nodul de modificat nu a fost gsit sau lista este vid), tergerea unui nod identificat prin informaia de nod (se scoate n eviden cazul cnd nodul ters este primul sau ultimul din list i cazul cnd acesta nu a fost gsit sau lista este vid), inserarea unui nod n list, nainte sau dup un nod reper (se va scoate n eviden cazul cnd inserarea se va face naintea primului nod sau dup ultimul nod i cazul cnd nodul reper nu a fost gsit sau lista este vid ), parcurgerea (afiarea coninutului) unei liste simplu nlnuite (se va scoate n eviden cazul cnd lista este vid). - modul de recunoatere a anumitor instane care uureaz implementarea (pstrarea sfritului listei pentru a facilita adugrile, reinerea nodului urm pentru a nlesni tergerile i inserrile naintea unui nod specificat etc.) Observaie : prezentarea operaiilor asupra nodurilor unei liste simplu nlnuite va fi nsoit de scheme i desene sugestive. Asigurarea conexiunii inverse (feedback) : durata estimativ este de 4 minute. Profesorul poate solicita elevilor prezentarea unor situaii problem, similare cu cele menionate anterior i pentru rezolvarea crora se poate folosi o list simplu nlnuit. Se va cere i s argumenteze exemplele date. Elevii vor identifica asemenea probleme i vor propune soluii n care se va folosi structura de date nvat, prezentndu-se avantajele unei asemenea implementri. Prezentarea temei pentru acas : durata estimat este de 2 minute. Profesorul propune tema pentru acas, iar elevii noteaz problema propus spre rezolvare i indicaiile de implementare ale profesorului i cer eventuale lmuriri suplimentare. - 28 -

3.1.2.1. Lista liniar simplu nlnuit


Aceast lecie se va ntinde pe parcursul a mai multor ore de curs i va urmri derularea etapelor de predare n ordinea n care au fost prezentate mai sus. O soluie de implementare a listelor liniare este sub forma unei nlanuiri de elemente cu aceeai structur, aflate n memorie la diverse adrese i legate ntre ele prin intermediul pointer-ilor. Scopul utilizrii listelor este de a economisi spaiu de memorie, motiv pentru care se folosete alocarea dinamic n locul celei statice (utilizat n cazul tablourilor). Accesul la un element al listei se poate face doar secvenial, parcurgnd elementele aflate naintea sa n nlanuire. Pentru a exploata avantajul listelor n ceea ce privete economia de spaiu de memorie, trebuie acordat o atenie deosebit operaiilor asupra listei. O list liniar simplu nlnuit este o structur de forma:

Fig. 1.3.1.2.1.Lista liniar simplu nlnuit Fiecare nod al listei este legat de nodul urmtor prin intermediul cmpului urm, iar p este o variabil pointer care indic primul nod al listei. Exist posibilitatea de a nlocui pointerul p care indic nceputul listei cu o variabil de tip nod, n care cmpul urm indic primul nod al listei, iar celelalte cmpuri ce ar conine informaia propriu-zis ar rmne neasignate. Utilizarea acestui nod de nceput simplific n anumite situaii prelucrarea listelor nlnuite. Dup cum observm, fiecare nod, cu excepia ultimului, reine adresa nodului urmtor. Structura de date care definete implementarea unei liste liniare simplu nlnuite n C se va defini ca o structur de date recursiv si presupunem c n zona destinat informaiei vom avea un cmp-cheie pentru identificarea nodului n list, iar restul cmpurilor din cadrul listei vor conine informaia propriu-zis. De asemenea, mai presupunem i c acest cmpcheie este de tip ntreg, iar cmpul destinat informaiei este de maxim 10 caractere. Lista poate fi definit n acest caz ca o structur (recursiv) de tipul:
struct nod { int cheie; char info[10] struct nod* urm; } typedef struct nod Tnod; typedef Tnod* ref;

Tehnici de inserie a nodurilor i de creare a listelor nlnuite - 29 -

Vom nota cu p variabila pointer care indic primul nod al listei, iar q o variabil pointer ajuttoare. Pentru a avea o list nlnuit se creeaz mai nti primul nod al listei prin funcia:
void ins_p(void) { q = malloc(sizeof(Tnod)); //1 printf("Intr. cheia : "); scanf("%d", &q->cheie); //2 printf("Intr. informatia : ");fflush(stdin);scanf("%s",q->info); //2 q->urm = NULL; //3 p = q; //4 }

Fig. 2.3.1.2.1. Crearea primului nod al listei liniare Inserarea unui nod n list (altul dect primul care asigur existena listei) se poate face n faa listei (la nceputul listei) sau n spatele listei liniare (la sfritul listei). Inserarea n faa listei presupune efectuarea urmtorilor pai: se aloc spaiu pentru noua nregistrare, se completeaz informaia (cmpurile info i cheia ), iar adresa urmtoare este cea din p, deci a primului element al listei. Variabila p va memora apoi adresa noii nregistrri. Funcia care realizeaz inserarea n faa listei este:
void ins_cf(void) { q = (ref)malloc(sizeof(Tnod)); //1 printf("Introduceti cheia nodului : "); fflush(stdin); scanf("%d", &q->cheie); //2 printf("Introduceti informatia utila : "); fflush(stdin); scanf("%s", q->info); //2 q->urm = p; //3 p = q; //4 }

- 30 -

Fig. 3.3.1.2.1. Inserare n faa listei Datorit faptului c inseria noului nod are loc de fiecare dat la nceputul listei, funcia de mai sus creeaz lista n ordinea invers a cheilor. Dac se dorete listarea n ordine natural, atunci este nevoie de o funcie care insereaz un nod la sfritul unei liste. Inserarea la sfritul listei. Aceast funcie se redacteaz mai simplu dac se cunoate locaia ultimului nod al listei. Teoretic, acest lucru nu prezint nici o dificultate deoarece se poate parcurge lista de la nceputul ei indicat prin p, pn la detectarea nodului care are cmpul urm==NULL. n practic, aceast soluie nu este convenabil deoarece parcurgerea ntregii liste este ineficient. Se prefer s se lucreze cu o variabil pointer ajuttoare q care indic mereu ultimul nod al listei, dup cum p indic primul nod al listei.
void incs (void) { r = (ref)malloc(sizeof(Tnod));//1 printf("Introduceti cheia nodului : "); fflush(stdin); scanf("%d", &r->cheie); //2 printf("Introduceti informatia utila : "); fflush(stdin); scanf("%s", r->info);//2 r->urm=NULL;//3 q->urm = r; //4 q = r;//5 }

Fig. 4.3.1.2.1. Inserarea la sfritul listei Traversarea unei liste nlnuite Prin traversarea unei liste se nelege executarea unei anumite operaii asupra tuturor nodurilor listei. Fie p pointerul care indic primul nod al listei i fie r o variabil pointer auxiliar. Atunci, funcia care realizeaz listarea elementelor listei va fi urmtoarea:
void listare(void) { r = p;

- 31 -

while(r!=NULL) { printf("Cheia = %d", r->cheie); printf("Informatia = %s", r->info); printf("\n"); r = r->urm; } }

O operaie care apare frecvent n practic este cutarea, adic depistarea unui nod care are cheia egal cu o valoare dat k:
void cautare(void) { int b=0; r=p; while ((b==0) && (r!=NULL)) if (r->cheie==k ) b=1; else r=r->urm; }

Operaia de cutare s-ar putea implementa printr-o funcie C care nu utilizeaz variabila boolean b.
void cautare(void) { r=p; while((r->cheie!=k && r!=NULL)) r=r->urm; }

n acest caz, la sfritul execuiei funciei, r va conine adresa nodului cu cheia dat, dac acesta exist n list, sau NULL, dac acesta nu exist n list. n ultimul caz ,nu are sens operaia r->cheie, astfel nct n funcia imlementat putem avea eroare sau nu. Urmtoarea variant a funciei de cutare este corect :
int cautare(int k) { r = p; while((r!=NULL) && (r->cheie!=k)) r = r->urm; if(r==NULL) return -1; /*returneaz -1 dac nu a gsit un nod cu cheia k*/ else return 1; /*returneaz 1 dac a gsit un nod cu cheia k*/ }

n cazul n care cutarea se termin fr a gsi elementul de cheie k, deci se termin pentru c s-a ajuns la sfritul listei (r==NULL) atunci nodul cu cheia k nu exist n list i se returneaz -1. Dac ns r este diferit de NULL, nseamn c nodul cu cheia k a fost gsit, r va conine adresa nodului de cheie k, i se returneaz 1.

- 32 -

Inseria unui nod ntr-un loc oarecare al listei Dup un nod anume. Fie r un pointer care indic un nod oarecare al listei i s o variabil reper ajuttoare. n aceste condiii, inseria unui nod dup nodul r se realizeaz astfel: se aloc spatiu pentru noul nod, se completeaza informaia (cmpurile cheia si info) pentru noul nod, i se face legtura cu nodul urmtor, apoi cu nodul precedent.
void insd(void) { s = (ref)malloc(sizeof(Tnod)); //1 printf("Introduceti cheia nodului : "); fflush(stdin); scanf("%d", &s->cheie); //2 printf("Introduceti informatia utila : "); fflush(stdin); scanf("%s", s->info); //2 s->urm = r->urm;// 3 - se realizeaz legtura cu nodul urmtor r->urm=s;// 4 - se realizeaz legtura cu nodul precedent }

Fig. 5.3.1.2.1. Inseria unui nod dup nodul r naintea unui nod. Dac se dorete inseria noului nod n lista liniar naintea unui nod indicat r, apare o complicaie generat de imposibilitatea practic de a afla simplu adresa predecesorului nodului r (Dup cum s-a precizat deja, n practic nu se admite parcurgerea de la nceput a listei pentru aflarea adresei nodului respective). Aceast problem se poate rezolva simplu cu ajutorul urmtoarei tehnici: se insereaz un nod dup nodul r, se asigneaz acest nod cu r, dup care se creeaz cmpurile cheie i info pentru nod i se asigneaz cu ele cmpurile corespunztoare ale vechiului nod r.
void insi(void) { s = (ref)malloc(sizeof(Tnod));//1 s=r;//2 r->urm = s;//3 printf("Introduceti cheia nodului : "); fflush(stdin); scanf("%d", &r->cheie); //4 printf("Introduceti informatia utila : "); fflush(stdin); scanf("%s", r->info);//4 }

- 33 -

Fig. 6.3.1.2.1. Inserarea unui nod naintea nodului r Tehnici de suprimare a nodurilor Se consider urmtoarea problem: se d un pointer r care indic un nod al listei liniare nlnuite i se cere s se suprime succesorul nodului r. Aceasta se poate realiza modificnd cmpul urm al nodului r :
s= r->urm; //1 r->urm = s->urm;//2

Fig. 7.3.1.2.1. Suprimarea unui nod Dac n prelucrrile ulterioare nu mai avem nevoie de succesor (nodul s), acesta poate fi suprimat prin free(s) care are ca efect eliberarea zonei de memorie ocupat de s. (Pentru a nu distruge iremediabil structurile de date create este necesar ca elevii s studieze cu atenie modul n care funcia free() este implementat de compilatorul pe care l au la dispoziie). Daca se dorete suprimarea chiar a nodului r, cum este dificil s cunoatem adresa predecesorului su (pentru a realiza legtura cu succesorul su), se utilizeaz urmtoarea tehnic: se aduce succesorul n locul lui r, apoi se suprim vechiul succesor. Aceasta se poate realiza prin secvena :
s= r->urm; r=s; free(s);//3

Lista liniar simplu nlnuit este prima structur dinamic prezentat elevilor. Pentru o mai bun nelegere a acestei structuri de date, pentru prezentarea listei liniare simplu nlnuit, dar i pentru ilustrarea etapelor care trebuie parcurse la realizarea operaiilor care se pot face cu aceast structur de date (la inserare i suprimare, mai puin la creare i traversare), se folosesc desene pe tabl, fie, folii pentru retroproiector sau pe calculatoare. - 34 -

Se vor propune elevilor spre rezolvare urmtoarele probleme, pentru fixarea cunotinelor : 1. Crearea i vizualizarea unei liste liniare simplu nlnuite, crearea fcndu-se cu inserare n fa, cu crearea separat a primului nod. 2. Crearea i vizualizarea unei liste liniare simplu nlnuite, crearea fcndu-se cu inserare n fa,fr crearea separat a primului nod. 3. Crearea i vizualizarea unei liste liniare simplu nlnuite, crearea fcndu-se cu inserare n spate,cu crearea separat a primului nod. n programul care urmeaz sunt prezentate cteva dintre operaiile care se pot face cu o list liniar simplu nlnuit i se va rezolva al doilea punct , adic lista liniar simplu nlnuit se va crea cu inserare n fa, cu crearea separat a primului nod. Prin intermediul funciei meniu() se va specifica tipul operaiei ce se dorete s se efectueze asupra listei.. Aceste operaii (creare, listare, adugare, tergere) sunt realizate de funciile cu acelai nume. 1) Creare. n probleme, de obicei, nu se cunoate de la nceput numrul de elemente al listei. nregistrrile se vor aduga prin apelul funciei ins_fa, care va fi apelat de fiecare dat cnd utilizatorul dorete adugarea unei noi nregistrri n list. 2) Listare. Atta timp ct nu am ajuns la sfritul listei, tiprim informaia util i trecem la nregistrarea urmtoare. Pentru listare, avem dou posibiliti: - funcia listare(void) va lista elementele listei liniare simplu nlnuit cu inserare n fa n ordinea invers a introducerii cheilor; - funcia listare2(ref r) va lista elementele unei liste liniare simplu nlnuit cu inserare n fa n ordinea introducerii cheilor. 3) Adugare. Operaia de adugare a unui element nou la list comport cunoaterea a dou informaii: informaia util a elementului din list dup care urmeaz s se fac adugarea; informaia util a elementului care urmeaz s fie adugat. Adugarea propriu-zis const n urmtoarele: poziionarea pe nregistrarea dup care trebuie s adugm noua nregistrare; alocarea spaiului pentru noua nregistrare; completarea informaiei utile pentru aceasta; completarea adresei urmtoare a noii nregistrri, care va fi adresa urmtoare a nregistrrii pe care suntem poziionai; cmpul de adres al nregistrrii pe care suntem poziionai va lua ca valoare adresa noii nregistrri. 4) tergere. Pentru a terge o nregistrare este necesar s cunoatem informaia util a acesteia. Se procedeaz n mod diferit n situaiile n care se terge prima nregistrare sau una diferit de prima. n cazul n care se terge prima nregistrare, se efectueaz operaiile: se caut n list nregistrarea pe care dorim s o tergem, prin apelul funciei cutare(); se face poziionarea pe nregistrarea care urmeaz a fi tears; cmpul de adres al nregistrrii precedente capt valoarea cmpului de adresa al nregistrrii curente; se elibereaz spaiul rezervat nregistrrii curente. Pentru tergerea ntregii liste se procedeaz astfel: se parcurge toat lista i pentru fiecare nregistrare se elibereaz spaiul ocupat de aceasta prin apelul funciei free(). - 35 -

Programul ce trebuie s se afle la sfritul orei pe fiecare calculator este urmtorul:


#include <stdio.h> #include <stdlib.h> #include <ctype.h>

/*pt functia malloc*/ /*pt functia toupper*/

typedef struct nod { int cheie; /*cheia dupa care are loc identificarea nodurilor in cadrul listei*/ char info[10]; /*informatia utila din cadrul listei*/ struct nod *urm; /*un pointer catre urmatorul nod din lista*/ }Tnod; typedef Tnod* ref; /*referinta catre o structura de tipul Tnod*/ ref p=NULL, q=NULL, r=NULL; /*p - pointer catre primul nod din lista q - pointer catre ultimul nod din lista r - pointer auxiliar*/ unsigned int dinamic=0; /*controleaza meniul ce se afiseaza*/ void meniu(void); void ins_fata(void); void listare(void); void creare(void); void delete_nod(int); int cautare(int); void delete_lista(void); void listare2(ref); main() { char c; printf("Crearea si vizualizarea unei liste liniare cu inserare in fata.\n"); do { meniu(); fflush(stdin); scanf("%c", &c); c = toupper(c); switch(c) { int cheie; case 'C': creare(); dinamic = 1; break; case 'L': listare(); break; case 'A': listare2(p); break; case 'D': printf("Introduceti cheia nodului de sters : "); fflush(stdin); scanf("%d", &cheie); delete_nod(cheie); break; case 'I': ins_fata(); break;

- 36 -

case 'S': printf("Introduceti cheia nodului de cautat : "); fflush(stdin); scanf("%d", &cheie); if(cautare(cheie)==1) printf("Informatia din nodul cu cheia \"%d\" este : %s\n", cheie, r->info); else printf("Nu exista nici un nod cu cheia \"%d\" !\n", cheie); break; case 'V': delete_lista(); printf("Spatiul ocupat de lista a fost eliberat\n"); dinamic = 0; break; default: printf("Comanda gresita!\n"); } } while(c!='E'); delete_lista(); printf("Spatiul ocupat de lista a fost eliberat\n");

void creare() /*Creaza lista prin apeluri succesive ale functiei ins_fata*/ { char c; do { ins_fata(); printf("Continuati(D/N) : "); fflush(stdin); scanf("%c", &c); c = toupper(c); } while(c=='D'); }/*sfarsit creare*/ void ins_fata(void) /*insereaza un nod in fata listei.*/ { r = (ref)malloc(sizeof(Tnod)); printf("Introduceti cheia nodului : "); fflush(stdin); scanf("%d", &r->cheie); printf("Introduceti informatia utila : "); fflush(stdin); scanf("%s", r->info); r->urm = p; p = r; }/*sfarsit ins_fata*/ void listare(void) /*listeaza elementele listei cu inserare in fata*/ { if(p==NULL) printf("Lista este vida!\n"); else { printf("Elementele listei sunt :\n"); r = p; while(r!=NULL) { printf("Cheia = %d ", r->cheie); printf("Informatia = %s", r->info); printf("\n");

- 37 -

r = r->urm; } }/*sfarsit listare*/ void listare2(ref r) { if(r!=NULL) { listare2(r->urm); printf("Cheia = %d ", r->cheie); printf("Informatia = %s\n", r->info); } } int cautare(int k) /*cauta nodul cu cheia k*/ { r = p; while((r!=NULL) && (r->cheie!=k)) r = r->urm; if(r==NULL) return -1; /*returneaza -1 daca nu a gasit un nod cu cheia k*/ else return 1; /*returneaza 1 daca a gasit un nod cu cheia k*/ }/*sfarsit cautare*/ void delete_nod(int k) /*sterge nodul cu cheia k*/ { if(p->cheie == k) { r = p->urm; free(p); p = r; printf("Nodul cu cheia \"%d\" a fost sters.\n", k); if(p==NULL) { dinamic = 0; printf("Lista este vida.\n"); } } else { r = p; q = p; while((r!=NULL) && (r->cheie!=k)) { q = r; r = r->urm; } if(r!=NULL) { q->urm = r->urm; free(r); r = NULL; printf("Nodul cu cheia \"%d\" a fost sters\n", k); } else printf("Nu exista nici un nod cu cheia \"%d\"\n", k); } }/*sfarsit delete_nod*/ }

- 38 -

void delete_lista(void) /*sterge ocupat*/ { for(r = p; r != NULL; r = q) { q = r->urm; free(r); r = NULL; } p = NULL; } /*sfarsit delete_lista*/

lista

liniara

<=>

elibereaza

spatiul

void meniu(void) { if(dinamic==0) printf("C. Crearea listei\n"); if(dinamic) { printf("I. Inserarea unui element la sfarsitul listei\n"); printf("S. Cauta un element dupa o cheie data\n"); printf("D. Sterge un element cu o cheie data\n"); printf("V. Sterge l.l.s.i.\n"); printf("L. Afiseaza lista liniara\n"); printf("A. Listeaza lista liniara in ordinea introducerii\n"); } printf("E. Exit\n"); printf("Tastati optiunea : "); }

Primul i ultimul exerciiu vor fi propuse ca tem pentru acas, innd cont de faptul c elevii au cunotinele necesare rezolvrii acestora. Dup prezentarea tuturor operaiilor care se pot realiza cu o list liniar simplu nlnuit, se propune construirea i tiprirea unei liste liniare simplu nlnuit, folosind recursivitatea. Se prezint elevilor algoritmul rezolvrii problemei, urmnd ca ei s scrie programul, eventual ca tem pentru acas. Exemplu: Construirea i tiprirea unei liste liniare simplu nlnuit folosind tehnici recursive. Funcia lista are sarcina de a construi lista liniar simplu nlnuit. La nceput se cere informaia util ( pentru simplificarea prezentrii informaia util este reprezentat de numere ntregi: 1,2, ..., n). n situaia n care aceasta este diferit de 0, valoare care semnific faptul c nu mai avem de adugat nici un element, se rezerv spaiu pentru noua nregistrare, se completeaz informaia util, iar cmpul urm va lua valoarea funciei de tip ref lista care se autoapeleaz. n ncheiere, lista va lua valoarea c a cmpului care reine adresa noului element. Este interesant s observm c iniial se creeaz lista simplu nlnuit fr a completa cmpul urm, aceast completare urmnd s se fac la revenirea n funcie. Pentru crearea unei liste cu dou nregistrri care au informaiile utile 1 i 2, rularea decurge astfel: se apeleaz funcia; se citete valoarea lui n i anume 1; se aloc spaiu pentru prima nregistrare; se completeaz informaia util; pentru a completa adresa urmtoare nregistrrii curente, se apeleaz din nou funcia; se citete valoarea lui n i anume 2; - 39 -

se aloc spaiu pentru a doua nregistrare; se completeaz informaia util cu 2; se apeleaz din nou funcia; se citete 0; funcia ia valoarea null; se revine din apel i se continu cu urmtoarea instruciune; cmpul de adres a celei de-a doua nregistrri va lua valoarea null; funcia capt valoarea adresei nregistrrii 2; se revine din apel; cmpul de adresa al primei nregistrri ia valoarea celei de-a doua nregistrri; funcia ia valoarea primei nregistrri; se revine n programul principal. Valoarea variabilei c a programului principal va fi, dup rulare, adresa primei nregistrri. Aceast lecie, referitoare la lista liniar simplu nlnuit, este o lecie mixt, realizndu-se att transmiterea de noi cunotine ct i formarea de priceperi i deprinderi. Metodele didactice folosite la aceast lecie sunt: conversaia euristic, metoda descoperirii, aplicaiile practice individuale. Pentru fixarea cunotinelor, urmeaz rezolvarea de aplicaii cu liste liniare simplu nlnuite. La leciile de aplicaii, elevii sunt mprii n grupe de cte doi elevi (n situaia n care dotarea material este suficient pentru a se asigura cel puin cte un calculator la doi elevi). n cadrul activitilor practice din laboratorul de informatic pot fi incluse probleme mai complicate din punctul de vedere al cerinelor de rezolvare i de prezentare ctre utilizator a rezultatelor dect exerciiile date pentru fixarea noiunilor. n general astfel de lucrri practice apar ca proiecte cu subiecte reale de utilitate imediat, cum ar fi : realizarea unor programe cu rol interdisciplinar i cu utilitate didactic, realizarea unor programe de tip lecii asistate de calculator pentru o anume disciplin, realizarea unor programe care s exploateze creativitatea i imaginaia (jocuri, interfee, foi volante ale clasei, material publicitar etc.). Proiectele respective sunt, de regul, realizate n echipe de doi-trei elevi.

3.1.2.1.1. Aplicaie - Sortarea topologic

Sortarea topologic este o aplicaie important a listelor. Se prezint elevilor algoritmul sortrii topologice, iar programul l vor realiza singuri, pe calculator, n grupe de cte doi elevi. n acest moment al leciei, se poate organiza un concurs ntre grupele de elevi, ctignd grupa care realizeaz un program corect n timpul cel mai scurt. Enunul problemei: Presupunem c dorim sortarea numerelor 1,2, .... n, numere care se gsesc ntr-o ordine oarecare, alta dect cea natural. Pentru a afla relaia n care se gsesc numerele, introducem un numr finit de perechi (i,j). O astfel de pereche ne spune c, n relaia de ordine considerat, i se afl naintea lui j.

- 40 -

Exemplul 1: Fie n=3 i citim perechile (3,1) i (3,2). Numrul 3 se afl naintea lui 1 i 3 se afl naintea lui 2. Apar dou soluii posibile: 3,1,2 i 3,2,1, ntruct nu avem nici o informaie asupra relaiei dintre 1 i 2. De aici rezult faptul c o astfel de problem poate avea mai multe soluii. Exemplul 2: Fie n=3 i citim (1,2), (2,3), (3,1). n acest caz, nu avem soluie. Din primele dou relaii, rezult c ordinea ar fi 1,2,3, dar relaia a 3-a contrazice aceast ordine. n concluzie, problema poate avea sau nu soluie, iar dac are, poate fi unic sau nu. Algoritmul urmtor furnizeaz o singur soluie atunci cnd problema admite soluii. n caz contrar, specific faptul c problema nu admite soluie. Vom exemplifica funcionarea algoritmului pe exemplul urmtor: Fie n=4 i se citesc perechile (3,4), (4,2), (1,2), (3,1). Pentru fiecare numr ntre 1 i n trebuie s avem urmtoarele informaii: numrul predecesorilor si; lista succesorilor si. Pentru aceasta, se folosesc doi vectori: contor, vector care reine numrul predecesorilor fiecrui k, k{1,...,n}; a, care reine adresele de nceput ale listelor de succesori ai fiecrui element. Pentru fiecare element exist o list simplu nlnuit a succesorilor si. Fiecare nregistrare din aceste liste conine dou cmpuri: succesorul; adresa urmtorului element din list. Iniial, n dreptul fiecrui element din vectorul contor se trece 0, iar n vectorul a se trece 0. Citirea unei perechi (i,j) nseamn efectuarea urmtoarelor operaii: incrementarea variabilei contor(j) (j are un predecesor, i anume i); adugarea lui j la lista succesorilor lui i. Pentru exemplul de mai sus avem: contor a 0 0 0 0 0 0 0 0 valorile iniiale ale celor doi vectori

0 0 contor a

0 0

0 al3

1 0

s-a citit (3,4) al3-adresa listei

- 41 -

0 0 contor a

1 0

0 al3

1 al4

s-a citit (3,4)

contor a

1 0

1 0

0 al3

1 al4

s-a citit (4,1) al3-adresa listei 3

2 1

contor s-a citit (1,2) a

1 al1 2

2 0

0 al3 4

1 al4 2 1

contor a 2 al1 2 2 0 0 al3 4 1 - 42 1 al4 2 1 s-a citit (3,1) al3-adresa listei 3

n continuare, se procedeaz astfel : o toate elementele care au 0 n cmpul contor se rein ntr-un vector c; o pentru fiecare element al vectorului c se procedeaz astfel : se tiprete; se marcheaz cu -1 cmpul su de contor; pentru toi succesorii si (aflai n lista succesorilor) se scade 1 din cmpul contor (acetia au un predecesor mai puin); se reia algoritmul dac nu este ndeplinit una din condiiile urmtoare : a) au fost tiprite toate elementele, caz n care algoritmul se ncheie cu succes; b) nu avem nici un element cu 0 n cmpul contor, caz n care relaiile au fost incoerente. n continuare se procedeaz astfel : contor a 1 al1 2 2 null -1 al3 4 1 0 al4 2 1 Se tiprete 3; se scade 1 din predecesorii lui 4 i 1; Se marcheaz cu -1 contorul lui 3;

contor a

0 al1 2

1 null

-1 al3 4 1

-1 al4 2 1

Se tiprete 4; se scade 1 din predecesorii lui 2 i 1; Se marcheaz cu -1 contorul lui 4;

contor a

-1 al1 2

0 null

-1 al3 4 1

-1 al4 2 1

Se tiprete 1; se scade din predecesorii lui 2; Se marcheaz cu -1 contorul lui 1;

- 43 -

Algoritmul are multe aplicaii, ca de exemplu : ordonarea unor activitati, atunci cnd ele sunt condiionate una de alta; ordonarea unor termeni care se cer explicai, pentru a-i putea explica prin alii deja prezentai. Algoritmul are complexitatea O(n 2 ). Odat sunt n extrageri i la fiecare extragere se parcurge lista succesorilor unui nod. Programul C care va trebui sa fie pe fiecare calculator arat astfel :
#include <stdio.h> #include <alloc.h> #include <conio.h> typedef struct Nod { int succ; struct Nod* urm; }Tnod; typedef Tnod* ref; ref a[100]; int n,m,i,j,k,gasit; int contor[100], c[100]; void adaug(int i, int j) { ref c,d; contor[j]++; c=a[i]; d=(ref)malloc(sizeof(Tnod)); d->urm=0; d->succ=j; if (c==0) a[i]=d; else { while(c->urm) c=c->urm; c->urm=d; } } void actual (int i) { ref c=a[i]; while (c) { contor[c->succ]--; c=c->urm; } } void main() { printf("n=");scanf("%d",&n); for(i=1;i<=n;i++) { contor[i]=0; a[i]=0; } while (i) { printf("Tastati i="); scanf("%d",&i); printf("Tastati j="); scanf("%d",&j); if (i) adaug(i,j); } m=n; do { k=1; gasit=0; for(i=1;i<=n;i++) if (contor[i]==0) { gasit=1; m--; c[k]=i; k++; contor[i]=-1; } for(i=1;i<=k-1;i++) { actual(c[i]); printf("actual %d \n", c[i]); } } while (gasit && m); if (m) printf("relatii contradictorii \n"); else printf("Totul e OK \n"); getch(); }

- 44 -

Leciile de aplicaii practice, deosebit de importante pentru aprofundarea cunotinelor, pentru formarea priceperilor i deprinderilor, se bazeaz pe metoda aplicaiilor practice individuale sau pe grupe de elevi.

3.1.2.2. Liste liniare dublu nlnuite


Unitatea de nvare : Structuri de date de tip list liniar dublu nlnuit. Detalieri de coninut : Abordarea leciei presupune cunoaterea de catre elevi a alocrii dinamice a variabilelor, alocarea i eliberarea efectiv a zonelor de memorie aferente, lucrul cu tipul pointer i tipul struct, deosebirea dintre variabilele de tip pointer i variabilele statice. Tipul leciei : mixt (verificare i comunicare de cunotine). Obiective operaionale : La sfritul acestei lecii elevii vor fi capabili s : poat defini o structur de date de tip list liniar dublu nlnuit. cunoasc i s foloseasc n aplicaii principalele operaii care se pot efectua cu nodurile (elementele) unei liste liniare dublu nlnuite. identifice situaiile n care este recomandabil utilizarea acestei structuri de date. foloseasc n mod optim n aplicaii liste liniare dublu nlnuite. Metode i procedee didactice : conversaia frontal i individual, explicaia, metoda analitic, munca independent, nvarea prin descoperire, problematizarea etc. Mijloace didactice : manualul, culegeri de probleme, tabla, calculatorul, retro(video)proiectorul. Momentele leciei : Momentul organizatoric : 2 minute, obiectivele urmrite fiind crearea unei atmosfere specifice bunei desfurri a activitii didactice care urmeaz. Verificarea temei pentru acas i a cunotinelor dobndite anterior : maxim 8 minute. Captarea ateniei, prezentarea titlului i a obiectivelor leciei noi : maxim 2 minute. Activitatea profesorului se poate prezenta sub forma : a) Se prezint o situaie-problem prin care se urmrete scoaterea n eviden a importanei utilizrii unei structuri de date de tip list liniar dublu nlnuit, insistndu-se asupra avantajelor pe care le prezint aceast structur n condiiile impuse de problem. b) Se subliniaz gama larg de probleme (gestionarea documentelor i reprezentrile/vizualizrile acestora n cadrul unei aplicaii concrete, gestionarea spaiului de memorie liber i/sau alocat explicit etc.) care vor putea fi soluionate elegant folosind structura de date de tip list. n ceea ce privete activitatea elevului, acesta ascult i noteaz cele prezentate de ctre profesor i pune ntrebri care s poat lmuri contextul n care se va desfura lecia.. Prezentarea noilor coninuturi : durata estimat poate fi de 12 minute. Profesorul poate prezenta succesiv : - definirea structurii de date ca o structur recursiva; - operaiile care se pot face cu nodurile unei liste liniare dublu nlnuite : adugarea de noduri la sfritul unei liste (se scoate n eviden cazul cnd lista este vid i - 45 -

cazul cnd mai exist noduri n list), modificarea unui nod identificat prin informaia de nod (se scoate n eviden cazul cnd nodul de modificat nu a fost gsit sau lista este vid), tergerea unui nod identificat prin informaia de nod (se scoate n eviden cazul cnd nodul ters este primul sau ultimul din list i cazul cnd acesta nu a fost gsit sau lista este vid), inserarea unui nod n list, nainte sau dup un nod reper (se va scoate n eviden cazul cnd inserarea se va face naintea primului nod sau dup ultimul nod i cazul cnd nodul reper nu a fost gsit sau lista este vid ), parcurgerea (afiarea coninutului) unei liste dublu nlnuite (se va scoate n eviden cazul cnd lista este vid). - modul de recunoatere a anumitor instane care uureaz implementarea (pstrarea sfritului listei pentru a facilita adugrile, reinerea nodurilor urm i ant pentru a nlesni tergerile i inserrile naintea unui nod specificat etc.) Observaie : prezentarea operaiilor asupra nodurilor unei liste dublu nlnuite va fi nsoit de scheme i desene sugestive. Asigurarea conexiunii inverse (feedback) : durata estimativ este de 4 minute. Profesorul poate solicita elevilor prezentarea unor situaii problem, similare cu cele menionate anterior i pentru rezolvarea crora se poate folosi o list simplu nlnuit. Se va cere i s argumenteze exemplele date. Elevii vor identifica asemenea probleme i vor propune soluii n care se va folosi structura de date nvat, prezentndu-se avantajele unei asemenea implementri. Prezentarea temei pentru acas : durata estimat este de 2 minute. Profesorul propune tema pentru acas, iar elevul noteaz problema propus spre rezolvare i indicaiile de implementare ale profesorului i cere eventuale lmuriri suplimentare. Dup o prezentare general a structurii de date de tip list dublu nlnuit se va prezenta acest tip de structur de date amnunit, lund fiecare operaie n parte i cu ajutorul desenelor sugestive. Unele aplicaii necesit acces rapid att la nodul precedent ct i la nodul urmtor unui nod dat. Acest lucru se poate realiza cu usurin dac vom memora n fiecare nod al listei liniare legatura "nainte" i legatura "napoi" a nodului respectiv, lucru care duce la structura de list liniar dublu nlanuit care are cmpurile anterior=adresa nodului dinainte i urmtor=adresa nodului urmtor. ntr-o list dublu nlanuit, spre deosebire de lista liniar simplu nlnuit, cunoatem pentru fiecare nod al listei att adresa predecesorului ct i adresa succesorului i, prin urmare, sunt nlturate toate neajunsurile legate de recunoaterea predecesorului de la liste liniare simplu nlnuite. Operaiile care se pot realiza cu o list dublu nlnuit sunt: 1. creare - o list dublu nlnuit se creeaz cu o singur nregistrare. Pentru a ajunge la numrul de nregistrri dorit, se utilizeaz funcii de adugare la stnga sau la dreapta; 2. adugare la dreapta; 3. adugare la stnga; 4. adugare n interiorul listei; 5. tergere din interiorul listei; 6. tergere la stnga listei; 7. tergere la dreapta listei; 8. listare de la stnga la dreapta; - 46 -

9. listare de la dreapta la stnga. Structura de date care implementeaz o list liniar dublu nlnuit este urmatoarea :
struct nod { int cheie; char info [10]; struct nod* ant,* urm; }; typedef struct nod Tnod typedef Tnod* ref;

O list dublu nlnuit permite inserarea uoar a unui nod fie la dreapta, fie la stnga unui nod dat r. Presupunem cunoscute operaiile de inserare n fa i n spate, listare i cutare de la listele liniare simplu nlnuite. n aceste cazuri, tratm lista dublu nlnuit asemntor unei liste simplu nlnuite dup cmpul urm.

Fig. 1. 3.1.2.2. Lista liniar dublu nlnuit n ceea ce privete operaia de suprimare a unui nod, presupunem pentru nceput c nodul de suprimat nu este nici primul, nici ultimul. Suprimarea elementului R se realizeaz astfel : se localizeaz nodul precedent al nodului R i se face cmpul urmtor al acestuia s indice nodul care urmeaz celui indicat de R, se modific cmpul anterior al nodului care urmeaz celui indicat de R, astfel nct s indice nodul precedent celui indicat de R.

Fig 2.3.1.2.2. Suprimarea nodului R Nodul suprimat este indicat de R, spaiul de memorie alocat lui putnd fi realizat n regim de alocare dinamic a memoriei.
void suprima(void) { ref pred,succ; pred=r->ant;/*1*/

- 47 -

suc=r->urm;/*2/ if(r->ant != NULL) pred->urm=succ;/*3/ if (r->urm != NULL) succ->ant=pred;/*4/ if (r==p) pr=p->urm; free(r);

Se vor face urmtoarele observaii : Testul dac nodul de suprimat este primul este necesar pentru a actualiza variabila pointer p, care indic mereu primul nod al listei liniare. Dac nodul de suprimat nu este primul, secvena de mai sus deruleaz corect i far testul r==p. Dup tergerea nodului r pointer din list, indiferent de cazul n care ne-am aflat, variabila r va marca n continuare nodul r pointer, far a-l putea folosi n alt scop. De aceea vom apela funcia free(r). Un dezavantaj al listelor dublu nlnuite l constituie spaiul prea mare de memorie datorat cmpului suplimentar din structura nodurilor ant. Dupa ce le-au fost prezentate elevilor operaiile de baz care se pot realiza cu listele dublu nlnuite se va mpri clasa n grupe de doi, respectiv trei elevi, urmnd ca fiecare grup s realizeze cte o operaie asupra listei. Dup realizarea operaiilor, fiecare grup va prezenta colegilor operaia nsoit de funcia ce o realizeaz, urmnd ca la sfritul orei toi elevii s aib pe calculatoare programul funcional. Programul pe care elevii vor trebui sa l realizeze este urmtorul: S se creeze o list liniar dublu nlnuit cu inserare n faa listei i s se realizeze asupra sa operaiile de cutare dup o cheie dat, inserarea unui element dup/naintea unui element de cheie dat, tergerea unui element de cheie dat, listarea elementelor listei n ordinea invers a introducerii cheilor. Se va propune ca tem pentru acas realizarea urmtoarelor operaii : - crearea listei liniare dublu nlmuit cu inserare n spatele listei; - suprimarea unei nregistrri ce urmeaz dup o nregistrare de cheie dat; - suprimarea unei nregistrri situat naintea unei nregistrri de cheie dat; - listarea elementelor listei liniare dublu nlnuit cu inserare n fa n ordinea introducerii cheilor.

- 48 -

void creare() GRUPA 1 { Creeaz o list liniar dublu nlnuit char c; prin apeluri succesive ale funciei insd_cf. printf("Introduceti primul nod}; O list dublu nlnuit se creeaz cu o insd_p(); printf("Continuati(D/N) : "); singur nregistrare, prin apelul funciei fflush(stdin); scanf("%c", &c); insd_p. Pentru a ajunge la numrul dorit de c = toupper(c); nregistrri, se utilizeaz funcii de while(c=='D') adugare la stnga sau la dreapta. {

-variabilele de tip referin s i d vor cpta insd_cf(); printf("Continuati(D/N) : valoarea acestei prime nregistrri (s semnific adresa nregistrrii cea mai din "); fflush(stdin); stnga, d adresa ultimei nregistrri din scanf("%c",&c); dreapta).
} c = toupper(c); } void insd_p(void) { p = malloc(sizeof(Tnod)); printf("Introduceti cheia : "); scanf("%d",&p->cheie); printf("Introduceti informatia :"); fflush(stdin); scanf("%s", p>info); p->urm = NULL; p->ant = NULL; } void insd_cf(void) { q = (ref)malloc(sizeof(Tnod)); printf("Introduceti cheia nodului: "); fflush(stdin); scanf("%d", &q>cheie); printf("Introduceti informatia : "); fflush(stdin); scanf("%s", q>info); q->urm = p; q->ant = NULL; p->ant = q; p = q; }

GRUPA 2 Pentru crearea primei nregistrri se urmeaz paii: - alocarea de spaiu pentru nregistrare; -citirea informaiei utile; -completarea nregistrrii cu informaia util; -completarea adreselor de legtur la stnga i la dreapta cu NULL ; GRUPA 3 Inserarea unei nregistrri (q) n faa unei liste liniare dublu nlnuit. Operaiile sunt urmtoarele : - alocarea spaiului pentru nregistrare - citirea informaiei utile; - completarea adresei din dreapta cu adresa celei mai din stnga nregistrri (reinut n variabila p); - completarea adresei din stnga cu NULL; - modificarea cmpului de adres la stnga al nregistrrii din p cu adresa noii nregistrri; p va lua adresa noii nregistrri, deoarece aceasta va fi cea mai din stnga.

- 49 -

GRUPA 4 Inserarea unei nregistrri (s) dup o nregistrare de cheie dat (r) ntr-o list liniar dublu nlnuit. Se vor realiza urmtoarele operaii : - se reine adresa dreapt a nregistrrii care urma n acest moment nregistrrii cu informaia util r; - alocarea spaiului pentru nregistrare; - citirea informaiei utile; - adresa stng a noii nregistrri ia valoarea adresei nregistrrii de informaie util r; - adresa dreapt a noii nregistrri ia valoarea adresei dreapta a nregistrrii cu informaia util r; - adresa dreapt a nregistrrii cu informaia util r ia valoarea adresei noii nregistrri. - dac nregistrarea r are successor, adresa stng a acestuia ia valoarea adresei noii nregistrri. GRUPA 5 Inserarea unei nregistrri (s) n faa unei nregistrri (r) de cheie dat ntr-o list liniar dublu nlnuit. Se vor realiza urmtoarele operaii : - se reine adresa stng a nregistrrii care preced n acest moment nregistrrii cu informaia util r; - alocarea spaiului pentru nregistrare; - citirea informaiei utile; - adresa stng a noii nregistrri ia valoarea adresei nregistrrii care precede nregistrarea cu informaia util r; - adresa dreapt a noii nregistrri ia valoarea adresei nregistrrii cu informaia util r; - adresa stng a nregistrrii cu informaia util r ia valoarea adresei noii nregistrri; - dac nregistrarea r are predecesor, adresa dreapt a acestuia ia valoarea adresei noii nregistrri; altfel noua nregistrare devine prima din list

void insd_d(void) { ref s,succ; succ = r->urm; s = malloc(sizeof(Tnod)); printf("Introduceti cheia : "); scanf("%d",&s->cheie); printf("Introduceti informaia: "); fflush(stdin); scanf("%s", s->info); s->ant = r; s->urm = succ; r->urm = s; if(succ!=NULL) succ->ant = s; }

void insd_i(void) { ref s,pred; pred = r->ant; s = malloc(sizeof(Tnod)); printf("Introduceti cheia : "); scanf("%d",&s->cheie); printf("Introduceti informatia : "); fflush(stdin); scanf("%s", s->info); s->ant = pred; s->urm = r; r->ant = s; if(pred!=NULL) pred->urm = s;/*7 *r nu e primul, are predecesor*/ else p = s; }

- 50 -

void suprima(void) GRUPA 6 { Suprimarea unei nregistrri (r) de cheie ref pred, succ; dat. Se efectueaz urmtoarele operaii: pred = r->ant; - cmpul de adres dreapta al succ = r->urm; if(r->ant!=NULL) nregistrrii care o precede pe aceasta pred->urm =succ; va lua valoarea cmpului de adres if(r->urm!=NULL) dreapta al nregistrrii care va fi succ->ant =pred; tears; if(r==p) - cmpul de adres stnga al p=p->urm; free(r); nregistrrii care urmeaz nregistrrii } care va fi tears va lua valoarea cmpului de adres stng al nregistrrii care se terge; - se elibereaz spaiul de memorie rezervat nregistrrii care se terge. void listare(void) GRUPA 7 { Listarea elementelor listei liniare dublu if(p==NULL) nlnuite cu inserare n fa n ordinea printf("Lista este vid!\n"); invers a introducerii cheilor. else { Se realizeaz urmtoarele operaii : printf("Elementele sunt:"); - se parcurge lista ct timp exist r = p; nregistrri i se afieaz informaia util. while(r!=NULL) { >cheie); >info); } printf("Cheia=%d",rprintf("Info=%s",rprintf("\n"); r = r->urm; } } void cautare(void) GRUPA 8 { Cutarea unei nregistrri de cheie dat n int b = 0; lista liniar dublu nlnuit se realizeaz r = p; astfel : while((b==0) && (r!=NULL)) if(r->cheie == k) - se parcurge lista pn se gsete b=1; nregistrarea de cheie dat. Dac se ajunge else r = r->urm; la sfritul listei i nu s-a gsit } nregistrarea, nseamn c ea nu exist n list.

La finalul predrii structurii de date de tip list liniar, elevii trebuie s fie capabili s defineasc:structuri recursive de date, structuri statice de date, structuri dinamice de date. De asemenea elevii trebuie s tie care sunt operaiile de baz asupra listelor liniare i s defineasc corect structura de tip list liniar implementat att prin tipul tablou ct i cu ajutorul pointer-ilor.Elevii mai trebuie s cunoasc i s implementeze n limbajul C funciile care realizeaz operaiile asupra listelor liniare. Este indicat s se propun elevilor spre rezolvare ct mai multe probleme care s utilizeze structura de date de tip list liniar implementat prin cele dou metode. - 51 -

4. Pachetul de programe LinearList

Pachetul de programe LinearList ilustreaz forma listei liniare nlnuit i operaiile care se pot executa cu aceasta. Aplicaia LinearList a fost realizat din dorina de a veni n sprijinul elevilor care studiaz aceast structur de date. Acest pachet de programe se poate folosi la ,,desenarea" operaiilor cu o list liniar nlnuit i are ca scop familiarizarea elevilor cu structura de date de tip list liniar i formarea priceperilor i deprinderilor de a realiza programe n care se utilizeaz aceast structur de date. Fiecare operaie care se poate realiza asupra elementelor unei liste liniare este prezentat amnunit, pornind de la descrierea operaiei i terminnd cu funcia C corespunztoare. Nu lipsesc nici desenele i pentru fiecare operaie sunt prezentate : descrierea operaiei; desenul; funcia C. Paii urmrii n realizarea operaiei i funcia C sunt afiate n paralel, etap cu etap, pentru ca elevii s poat urmri ce se ntmpl cu lista la efectuarea unei etape a operaiei respective, iar desenul ilustreaz efectul descris n etapa respectiv.

4.1. Prezentarea aplicaiei

La lansarea n execuie, pe ecran se afieaz prima fereastr a aplicaiei ce conine o prezentare a scopului acestei aplicaii i dou butoane de opiuni: Lista i Help . Selectarea unei opiuni se face printr-un clic pe opiunea dorit. Alegerea opiunii Lista are ca efect afiarea noiunilor de baz despre lista liniar i permite utilizatorului s aleag una din opiunile : vizualizarea listei implementat prin tipul tablou, sau vizualizarea listei alocat cu ajutorul tipului pointer. Dac se alege butonul Pointer se va deschide o fereastr care va prezenta forma listei, semnificaia cmpurilor unui nod i definirea n C a tipului list liniar simplu nlnuit. De asemenea, fereastra va mai conine i un buton Operaii care, atunci cnd este acionat va deschide un meniu cu operaiile care se pot realiza asupra listei liniare simplu nlnuit, i anume : Creare Listare Cutare Inserare Suprimare Fiecare operaie este prezentat n cte o fereastr. Pentru vizualizarea operaiei dorite este suficient acionarea butonului corespunztor respectivei operaii. Inserarea ofer utilizatorului posibilitatea de a alege una din cele patru tehnici de inserie: inserarea n faa listei; - 52 -

inserarea la sfritul listei; inserarea dup un nod anume; inserarea naintea unui nod. Fereastra de suprimare permite, de asemenea, utilizatorului s aleag una din cele dou metode de suprimare : suprimarea unui nod; suprimarea succesorului unui nod. Dac se acioneaz butonul Tablou se va deschide o fereastr care va prezenta forma listei, semnificaia cmpurilor unui nod i definirea n C a tipului list liniar implementat prin tipul tablou. Similar cu fereastra introductiv de la lista liniar implementat prin tipul pointer, fereastra va mai conine i un buton Operaii care, atunci cnd este acionat va deschide un meniu cu operaiile care se pot realiza asupra listei liniare simplu nlnuit, i anume : Creare Listare Inserare Suprimare Pentru fiecare operaie se face mai nti o descriere a sa, apoi sunt prezentate etapele realizrii operaiei, o figur ilustrativ i funcia C care realizeaz operaia respectiv. Fiecare etap este afiat cu alt culoare, culoare care se pstreaz att n desen ct i n funcie. Descrierea etapelor, desenul i funcia C se afieaz n paralel, adic: se descrie etapa care se realizeaz; se scrie instruciunea (sau instruciunile) C care modeleaz etapa respectiv. se ilustreaz n desen efectul etapei efectuate; Dup o pauz se continu n acelai mod cu urmtoarele etape pn la realizarea operaiei respective. Astfel, elevii vor reine mai uor operaia descris, deoarece au vzut n desen ce se ntmpl cu lista liniar la fiecare pas al operaiei, n condiiile n care au afiate pe ecran descrierea operaiei, dar i funcia C corespunztoare. Pentru exemplificarea lucrului cu liste liniare am realizat i cteva exemple ce vor putea fi rulate acionnd butonul Exemple. La listele liniare simplu nlnuite create cu ajutorul tipului pointer am realizat dou programe care prezint operaiile care se pot realiza cu listele liniare simplu nlnuite. Crearea listei se va face n unul din cele dou moduri prezentate de aplicaie : prin inserarea unui nou element n faa listei, sau n spatele listei. Numele butoanelor sunt sugestive : L_fa, respectiv L_spate. Elevii vor putea crea propriile liste i vor avea posibilitatea s realizeze asupra lor toate operaiile prezentate pe parcursul aplicaiei. La nchiderea unei ferestre, se revine n fereastra anterioar, cu observaia c o fereastr nu poate fi nchis n cazul n care conine un submeniu activat. Opiunea Help conine informaii despre aplicaie: modul de selectare a unei opiuni i coninutul ferestrelor corespunztoare operaiilor. Aplicaia a fost realizat n Borland C, innd cont c este o aplicaie cu scop didactic iar n programa colar sunt incluse lecii de grafic n C.

- 53 -

4.2. Elemente de implementare

n procesul de realizare a aplicaiei am folosit fiierul surs linearlist.cpp, precum i fiierele header desene.h, mouse.h, ins_tot.h , exfata.h, llfata.h i llspate.h. Fiierul mouse.h conine rutinele de comunicare cu mouse-ul, fiierul desene.h conine definiiile funciilor de desenare, iar n fiierul ins_tot.h am inclus funciile corespunztoare tuturor operaiilor care se pot realiza asupra listelor liniare. Fiierele exfata.h, llfata.h i llspate.h conin programele de creare a listei liniare simplu nlnuite implementat att prin tipul tablou (exfata.h), ct i prin intermediul pointer-ilor (llfata.h i llspate.h). Fiierul surs linearlist.cpp conine iniializarea modului grafic i funcia main() care apeleaz funcia de deschidere a primei pagini a aplicaiei. nc de la apariia sa la nceputul anilor '70 limbajul C s-a impus ca lider de necontestat pentru programarea de sistem. Aceasta din urm cuprinde o clas larg de programe care interacioneaz foarte strns cu calculatorul i a cror performan o afecteaz pe a tuturor celorlalte. Un exemplu tipic de astfel de program este sistemul de operare. (El este singurul program care - de exemplu - interacioneaz cu discul. Toate celelalte programe cer serviciile lui pentru acest scop, prin funciile de lucru cu fiiere.) Una din calitile C-ului este suportul pe care l ofer pentru dezvoltarea de programe mari, eventual lucrate n echip. Pentru ca un program s poat fi scris de mai muli programatori trebuie ca el s poat fi descompus n pri independente - ct mai mult una de alta, care s poat fi concepute, compilate, testate eventual separat. O categorie de astfel de pri sunt bibliotecile. Unele operaii foarte utile sunt totdeauna aceleai (de exemplu funciile matematice (sinus, cosinus, exponen'tiale)) i pot fi scrise odat pentru totdeauna de un programator, fiind apoi folosite de toi utilizatorii. Aceste funcii sunt livrate adesea de firme sub forma unor biblioteci de funcii. Chiar i cnd un singur programator este implicat, mprirea unui program n pri puin dependente una de alta este de foarte mare ajutor pentru scrierea, dar mai ales depanarea rezultatului. Este deci foarte util s poi mpri un program n mai multe texte, fiecare ntr-un fiier separat. Aceast mprire se poate face n foarte multe feluri; de preferin toate funciile / variabilele/procedurile etc. care fac ceva nrudit trebuie sa fie puse n acelai fiier. Numele unui astfel de fiier este modul. Limbajul C pune la dispoziie nite mecanisme excelente pentru scrierea de programe mari. Aceste mecanisme permit : scrierea unui program din mai multe buci, care se pot compila separate; reutilizarea bucilor n programe diferite sub forma bibliotecilor; o gestiune relativ simpl a schimbrilor dintr-un modul datorit header-elor care grupeaz declaraiile obiectelor exportate. Realizarea de biblioteci ale utilizatorului Pentru a realiza biblioteci proprii, utilizatorul trebuie s grupeze funciile dup un anume criteriu ntr-un fiier text cruia i atribuie un nume adecvat coninutului i pe care l salveaz cu extensia .h. n programul care va folosi funcii din aceast bibliotec, se va gsi o directiv de preprocesare de tipul #include nume.h, unde nume este numele pe care l-a ales utilizatorul pentru bibliotec, iar obligaia de a folosi ghilimelele este pentru a dirija cutarea bibliotecii n directorul curent (nu n directoarele implicite ale BorlandC, Bin i Include ). - 54 -

Compilarea Cunoaterea fazelor compilrii este esenial pentru scrierea unor programe corecte n C. Dac un obiect este folosit fr a fi declarat, se obin erori, sau codul generat este incorect. Asta poate da natere la multe bug-uri. Un modul nu poate ti nimic despre obiectele globale definite n alte module pn n clipa legrii. Compilarea este format din trei faze independente, care sunt realizate de obicei de trei programe distincte, care se execut unul dup altul sau n paralel. Preprocesarea Preprocesorul este de obicei un program separat, care se numete `cpp' (C PreProcessor). Numele su vine de la faptul c el realizeaz o procesare nainte (pre) de compilarea propriu-zis. Preprocesorul este un program care prelucreaz texte. El primete un text iar rezultatul lui este tot un text. n principiu preprocesorul parcurge toate textele care-i sunt specificate de sus n jos, lucrnd pe linii, cutnd comenzi pentru el (numite directive), pe care le execut. Comenzile pentru preprocesor ncep cu un semn diez (#) n prima coloan. Preprocesorul C are trei mari grupe de comenzi: #include #define / #undef #if / #else / #endif / #ifndef Dup cum arat i numele fiierelor (faptul c se termin cu .h), acestea sunt fiiere header, care conin declaraiile unor obiecte exportate de alte module, importate de modulul curent. Cnd preprocesorul execut directiva #include, el gsete header-ul indicat (sau dac nu, oprete compilarea raportnd o eroare) i substituie linia #include cu textul header-ului. Dup aceea continu preprocesarea din acelai punct, prelucrnd deci textul tocmai introdus (care poate include alte header-e la rndul lui). Compilarea propriu-zis Datorit includerii, fiierele preprocesate conin deja declaraiile obiectelor importate. Apoi ele sunt compilate separat. Rezultatul acestei compilri este ceea ce se numete modul obiect (object file). Se obine cte unul pentru fiecare modul C iniial. Un modul (fiier) obiect este un amestec de program compilat (cod main) i variate informaii. Tot textul C al modulului a fost compilat n cod main, ns referinele la simboluri externe din alte module nu au putut fi satisfcute, pentru c aceste module sunt compilate separat. De aceea modulul obiect conine o list a simbolurilor nesatisfcute, indicnd i locurile unde sunt folosite. n plus mai conine i o list a simbolurilor exportate de modul. De asemenea, un modul obiect are o parte cu informaii numite de relocare. Acestea sunt necesare pentru c toate salturile din codul compilat sar la nite adrese care se vor schimba probabil atunci cnd modulul obiect va fi pus cap la cap cu altele pentru a forma executabilul. Adesea modulul obiect mai conine i alte informaii care sunt necesare pentru depanarea programului rezultat. Aceste informaii arat cror fiiere surs i cror linii (C) le corespund feluritele instruciuni din codul main. Cteodat faza de compilare propriuzis este format din dou pri independente i fcute de programe separate. O prim faz genereaz un program n limbaj de asamblare, iar a doua faz asambleaz programul pentru a obine un fiier obiect.

- 55 -

Linkeditarea Fiecare modul surs este compilat separat ntr-un modul obiect. Modulele obiect au o mulime de referine nesatisfcute (la obiectele importate). Legarea modulelor (implicnd completarea referinelor obiectelor globale, relocarea codului) este fcut de ultima faz a compilrii, numit linkeditare. Argumentele ei sunt module obiect. Rezultatul obinut de la linker este n fine un program executabil sub sistemul de operare pentru care lucreaz linker-ul. Un astfel de fiier are ns o structur destul de complicat, folosit de sistemul de operare pentru dou scopuri: el conine informaii despre structura nsi a fiierului executabil (ct de lung este codul, ct de lungi sunt datele, sistemul de operare pentru care merge, dac folosete biblioteci ncrcate dinamic, eventuale date de relocare etc.) i informaii de depanare, care sunt folosite cnd programul este depanat. Aceste informaii sunt preluate din fiierele obiect, dac existau, i n principiu indic din ce surse C provin instruciunile din executabilul final. Aceste informaii pot fi scoase din program, dac nu mai este nevoie ca el s fie depanat.

4.2.1. Elemente de grafic pe calculator


a) Resurse necesare - biblioteca de rutine grafice oferit de limbajul C/ C++ (graphics.h) - plac grafic tip VGA sau mai sus i driver-ul corespunztor b) Alegerea modului de lucru Un mod de lucru grafic este caracterizat de ofertele privind : rezoluia, paleta de culori i numrul paginilor de memorie video (o pagin reinnd informaiile grafice ale unui ecran). Selectarea i activarea unui mod de lucru grafic dintre cele oferite de driver se realizeaz cu rutina : initgraph(driver, mod_lucru, calea_ctre_bgi), unde driver i mod_lucru sunt variabile ntregi, iar calea ctre bgi (Borland Graphics Interface) este un ir de caractere. Uzual, dintre opiunile pentru driver se alege detect (sau constanta 0), altfel identificarea driver-ului i alegerea celui mai bun mod de lucru fcndu-se automat. Parametrul mod_lucru este de ieire. O iniializare trebuie verificat dac s-a realizat corect prin utilizarea funciei fr parametri graphresult, care n caz de success trebuie s ntoarc valoarea 0. Odat activat modul grafic, afiarea pe monitor n mod text nu mai este permis, ci va trebui s se scrie tot n mod grafic. La terminarea lucrului din mod grafic trebuie refcute setrile iniiale i nchis accesul oferit de iniializare. Aceste operaii sunt asigurate de rutinele fr parametri : clearviewport i closegraph. Modul grafic curent se poate afla apelnd funcia getgraphmode(). nainte de a apela getgraphmode() , programul trebuie s realizeze cu succes una din funciile initgraph sau setgraphmode. setgraphmode(mod_grafic) seteaz sistemul n mod grafic i terge ecranul. Aceast funcie selecteaz un mod grafic care poate fi diferit de cel implicit setat de initgraph. terge ecranul apoi reseteaz toate setrile grafice la cele iniiale. Mod_grafic trebuie s fie un mod valid pentru driver-ul curent. - 56 -

Se poate folosi setgraphmode mpreun cu restorecrtmode pentru a schimba ntre modul grafic i modul text. restorecrtmode() restaureaz modul ecranului la setrile detectate de initgraph. Mulimea culorilor care pot fi afiate simultan pe ecran se numeste palet. La iniializarea modului grafic, se seteaz o palet implicita. Paleta se definete cu ajutorul unui tablou de 16 elemente pentru adaptorul EGA. Elementele acestui tablou au valori din intervalul [0,63], fiecare element reprezentnd codul unei culori. Codurile culorilor din paleta implicit au denumiri simbolice definite n fiierul graphics.h. Ele au prefixul EGA. Exemplu : denumire simbolic culoare Black - 0 Blue - 1 Cyan - 2 Yellow 14 White - 15 Culoarea fondului (background) este ntotdeauna cea corespunztoare indicelui 0 iar culoarea pentru desenare este cea corespunzroare indicelui 15. Culoarea de fond poate fi modificat cu ajutorul funciei setbkcolor(culoare), iar culoarea pentru desenare poate fi modificat cu ajutorul funciei setcolor(culoare). c) Trasarea de puncte i linii Poziia pe care un pixel o are pe ecran se definete printr-un sistem binar : (x,y), unde x definete coloana n care este afiat pixelul, iar y definete linia n care este afiat pixelul. Sunt puse la dispoziie rutine de plasare a unui punct de o anumit culoare pe ecran putpixel(x,y,culoare), de deplasare la un punct anume moveto(x,y), de trasare a unei linii ncepnd de la punctul curent (x,y) ctre alt punct (z,w) lineto(z,w). Pentru trasarea unui segment trebuie specificat aspectul liniei pentru acel segment cu ajutorul rutinei setlinestyle(tip_linie,model,grosime). Tipul liniei poate fi : continu (0), punctat (1), linie_punct (2), ntrerupt (3), definit de utilizator (4). Modelul liniei este de valoare 0, dac tipul de linie nu este definit de utilizator. Grosimea poate fi : normal (1), gros (3). Pentru determinarea coordonatelor maxime de pe axa x, respectiv y pentru driver-ul i modul curent, se apeleaz funciile getmaxx() i getmaxy(). De exemplu, pentru driverul CGA, n modul 320 x 200, getmaxx() returneaz 319 iar getmaxy() returneaz 199. Pentru determinarea poziiilor curente pe axa x, respectiv y, folosim funciile getx() i gety(). Aceste valori depind de viewport. d) Scrierea textelor Pentru scrierea textelor n mod grafic se definesc nti atributele caracterelor din text cu rutina settextstyle(stil_caracter, direcie, mrime). Stilul caracterului : font implicit (0), font triplu (1), font mic (2), font sansseriff (3), font gotic (4). Direcia scrierii poate fi orizontal (0) sau vertical (1). Mrimea capt valori ntre 0 i 10. Stabilirea locului de scriere fa de punctul curent se precizeaz cu rutina settextjustify(orizontal, vertical), pentru fiecare parametru n parte specificndu-se : n dreapta/deasupra punctului curent (0), de o parte i de alta (1), sau n stnga/sub punctul curent (2). Scrierea propriu-zis a textului din variabila ir este realizat de rutina outtextxy(x,y,ir).

- 57 -

e) Desenarea figurilor geometrice Modul de umplere a figurii se precizeaz prin setfillstyle(tip umplere,culoare), unde tip umplere are doisprezece variante. Pentru desenarea unui dreptunghi se folosete rutina rectangle(stnga, sus, dreapta, jos), unde (stnga, sus) reprezint coordonatele colului de sus din partea stng, iar (dreapta, jos) reprezint coordonatele colului de jos din partea dreapt. Rutina bar(stnga, sus, dreapta, jos) realizeaz desenarea unui dreptunghi plin, umplerea realizndu-se cu stilul de umplere precizat prin setfillstyle. bar3d(left, top, right, bottom, adncime, topflag) deseneaz un dreptunghi tridimensional, apoi l umple folosind tipul de umplere i culoarea specificate. Adncimea este specificat n pixeli, (left, top) reprezint coordonatele colului din stnga sus iar (right, bottom) cele ale colului din dreapta jos. Topflag specific dac partea de sus a dreptunghiului este tridimensional (o valoare mai mare ca 0) sau nu (0). f) Elemente de animaie Exist patru moduri de a crea animaia pe ecran. O metod de creare a animaiei este prin redesenarea cu tergere a figurii (pentru realizarea iluziei de micare) n acelai loc n care ea a fost desenat prima dat, dup o perioad de ntrziere aleas convenabil (delay(nr_milisecunde)). Redesenarea cu tergere se realizeaz prin rutina setwritemode(1) care n mod normal are parametrul de valoare 0. Valoarea 1 a parametrului specific modul de scriere peste, adic xorput, bazat pe funcia logic xor. Astfel, la rescrierea aceleiai informaii n aceeai zon ecran se vor ntlni cei doi pixeli corespunztori punctului curent, ambii de valoare 1 sau ambii de valoare 0, ceea ce va da fals pentru funcia logic i astfel informaia se terge din acel loc prin rescriere cu culoarea fondului. Fiierul desene.h conine definiiile funciilor de desenare utilizate de aplicaie, precum : locaie(), locaie_nou(), tablou(), tablou_nou(), erase(), lined(), arrow_right(), arrow_left(), arrow_up(), arrow_down(), unpressed() , pressed(), window(). Funcia locaie() deseneaz, dup cum indic i numele su, locaia unui element al listei liniare.
locatie(int x,int y,int c) { setcolor(6); setlinestyle(SOLID_LINE,1,1); rectangle(x,y,x+60,y+30); lined(x+30,y,x+30,y+30,6); settextstyle(2,HORIZ_DIR,2); if (c==1) outtextxy(x+43,y+10,"NULL"); return 0; }

Rezultatul apelrii acestei funcii este urmtorul : dac c=0, dac c=1,

NULL

Cnd se dorete inserarea unui element n lista liniar simplu nlnuit se apeleaz funcia locaie_nou(),

- 58 -

locatie_noua(int x,int y,int cul) { setlinestyle(DOTTED_LINE,1,1); rectangle(x,y,x+60,y+30); lined(x+30,y,x+30,y+30,cul); return 0; }

care are ca efect desenarea : Sgeile fac legtura ntre nodurile listei, dar sunt folosite i pentru a indica paii fiecrei operaii care se realizeaz asupra listelor.
arrow_right(int x, int y, int lung) { line(x,y,x+lung,y); x=x+lung; line(x-2,y-2,x-2,y+2); line(x-2,y-2,x,y); line(x-2,y+2,x,y); return 0; }

Rezultatul este : Similar sunt realizate i funciile arrow_left(), arrow_up(), arrow_down(), prin modificarea argumentelor funciilor line. Apelul functiilor locaie() i arrow_right(), n succesiunea i cu argumentele necesare, au ca efect :
NULL

n ferestrele aplicaiei se ntlnesc butoane care, acionate, au ca efect deschiderea paginii corespunztoare scopului butonului. Pentru crearea butoanelor am folosit funcia unpressed().
unpressed(int x,int y,char *string) { setlinestyle(SOLID_LINE,1,NORM_WIDTH); setfillstyle(SOLID_FILL,CYAN); bar(x, y, x+50, y+30); setcolor(LIGHTCYAN); line(x,y,x+50,y); line(x,y,x,y+30); setcolor(EGA_DARKGRAY); line(x,y+30,x+50,y+30); line(x+2,y+31,x+50,y+31); line(x+50,y,x+50,y+30); line(x+51,y,x+51,y+31); setcolor(BLUE); settextstyle(2,0,4);

- 59 -

outtextxy(x+5,y+12,string); return 0;

Pentru crearea unui efect de buton am folosit funcia bar care deseneaz o cutie i am desenat linii de diferite culori pe marginile cutiei : o linie alb n partea superioar a cutiei i o linie nchis la culoare n partea inferioar. Pe respectivul buton va fi scris numele care identific aciunea corespunztoare acionrii sale. Dac se acioneaz butonul, trebuie ca aceast aciune s fie prezentat i vizual prin crearea unui efect de apsare a butonului. Funcia pressed() realizeaz acest lucru.
pressed(int x,int y,char *string) { setfillstyle(SOLID_FILL,CYAN); bar(x, y, x+50, y+30); setcolor(EGA_DARKGRAY); line(x,y,x+50,y); line(x-1,y-1,x+51,y-1); line(x,y,x,y+30); line(x-1,y-1,x-1,y+30); setcolor(LIGHTCYAN); line(x,y+30,x+50,y+30); line(x-1,y+31,x+50,y+31); line(x+50,y,x+50,y+30); line(x+51,y-1,x+51,y+31); setlinestyle(DOTTED_LINE,1,NORM_WIDTH);

setcolor(EGA_DARKGRAY);

rectangle(x+4,y+4,x+46,y+2 setcolor(BLUE); settextstyle(2,0,4); outtextxy(x+10,y+12,string); return 0;

Fiecare fereastr a aplicaiei va fi de forma : Operaii asupra listei liniare simplu nlnuite Prezentarea operaiei Desenul care ilustreaz etapele realizrii operaiei

Prezentarea etapelor operaiei

Instruciunea C corespunztoare

- 60 -

Funcia window() creaz bara de sus a aplicaiei, precum i butonul de exit.


window() { setlinestyle(0,1,1); setfillstyle(1,11); //7 setcolor(4); bar(0,0,getmaxx(),10); setfillstyle(1,13); bar(getmaxx()-10,0,getmaxx(),10); setcolor(7); line(getmaxx()-10,0,getmaxx(),10); line(getmaxx()-10,10,getmaxx(),0); return 0; }

4.2.2. Introducere n programarea mouse-ului


Dac un program care are o interfa plcut nu ofer suport pentru mouse s-ar putea spune c nu ofer o interfa uor de folosit. Programarea mouse-ului este relativ simpl la nivel jos, dar apar dificulti cnd trebuie s se foloseasc butoane i pointeri de mouse animai. Sunt multe ci de a accesa mouse-ul : folosind un utilitar care deja conine rutinele mouse sau programnd direct cu mouse-ul. Sunt dou metode de comunicare cu mouseul : prin intermediul portului serial; prin driver-ul de mouse, folosind ntreruperea 0x33. Citirea portului serial poate fi o operaie greoaie deoarece mouse-ul trebuie detectat, iar pe un calculator sunt dou sau chiar mai multe porturi seriale, fiecare putnd fi conectate la mouse. O alt problem poate s apar deoarece mouse-ul ar putea folosi un port PS/2 sau USB. Driver-ul de mouse este un driver de dispozitiv care ajut sistemul de operare s determine ce tip de mouse este disponibil. Driver-ul de mouse este instalat pe calculatorul utilizatorului i ofer un mod simplu de a detecta existena mouse-ului i transmiterea de mesaje precum acionarea sau eliberarea butoanelor mouse-ului. Folosirea driver-ului de mouse asigur funcionarea codului indiferent de tipul de mouse folosit. Driver-ul mai ofer i suport pentru pointer-ul de mouse, dar este limitat la dou culori de pointer. ntreruperi software Pentru a realiza interfaa grafic ntre sistemul de operare sau programele scrise de utilizatori i diferitele componente ale sistemului de calcul, BIOS-ul pune la dispoziie o serie de rutine care, dei nu foarte uor de manipulat, ofer un instrument de lucru foarte puternic. Aceste rutine sunt accesibile sub forma unor ntreruperi software, care pot sau nu s fie generate de o ntrerupere hard. ntreruperile sunt funcii speciale construite n BIOS. Sunt sute de ntreruperi n BIOS i funciile mouse-ului utilizeaz ntreruperi 0x33. Cnd este apelat o ntrerupere, orice proces care ruleaz va fi ntrerupt pentru a permite execuia procesului solicitat. Aceast ntrerupere este apelat prin setarea valorii de registru corespunztoare, prin apelarea ntreruperii i apoi prin punerea rezultatului n acelai - 61 -

registru. Programatorul poate inspecta valoarea primit ca rezultat n respectivul registru pentru a determina dac ntreruperea a fost realizat cu succes sau dac a aprut vreo eroare. Apelul ntreruperilor Pentru a accesa ntreruperile este nevoie de funcii sau rutine speciale care pot s acceseze att regitri microprocesorului ct i ntreruperile. n C sunt rutine speciale care trateaz ntreruperile. Fiierul header pentru aceast bibliotec este <dos.h> i trebuie inclus prin : #include <dos.h>
int86(int intrptnum, struct REGS *inregs, struct REGS *outregs); int86x(int intrptnum, struct REGS *inregs, struct REGS *outregs, struct SREGS *segregs);

nainte de execuia ntreruperii software, aceste funcii copiaz valorile de registru din inregs n regitri. De exemplu, dac dorim s folosim ntreruperea 0x33, 0x00, care s verifice existena driver-ului de mouse, vom proceda astfel :
Mouse() { union REGS i,o; i.x.ax=0; int86(0x33,&i,&o); return (o.h.al); }

Dup ce este apelat ntreruperea, valoarea returnat va fi n o (outregs). Dac mouse-ul nu este instalat, valoarea al din REGS va fi 0xFFFF. Se pot folosi aceleai variabile att pentru intrri ct i pentru ieiri.
int86(0x33,&i,&i);

Valoarea de ieire va fi trimis la REGS. n codul de mai sus folosim funcia int86 deoarece registrul este de la AX la DX. Sunt i cazuri cnd este nevoie s se acceseze regitri precum ES, DI sau SI, cnd trebuie folosit funcia int86x. ntreruperi 0x33. Controlul mouse-ului i ntreruperile utilizator Pentru a obine controlul asupra mouse-ului se poate accesa mouse-ul prin dou metode : folosind bucle sau ntreruperi definite de utilizator. Buclele Folosirea buclelor este metoda cea mai simpl i cel mai uor de neles. Metoda const n crearea unei bucle care s caute constant locaia cursorului i starea butoanelor mouse-ului. Locaia cursorului poate fi citit prin intermediul ntreruperii (0x33,0x03) pentru locaia cursorului, ntreruperea (0x33,0x05)- apsarea mouse-ului i ntreruperea (0x33,0x06) eliberarea mouse-ului. Cnd este gsit o anumit locaie sau o anumit operaie asupra butoanelor a fost realizat (folosind if sau switch), se poate realiza o anumit operaie. Aceast metod are dezavantajul c nu se poate executa nici o operaie n timpul execuiei buclei. Aceasta nseamn c, dac este controlul la mouse, nici un alt control nu poate fi accesat (de exemplu tastatura). Vom avea astfel o bucl care va controla doar mouse-ul. Sunt diverse metode pentru nlturarea acestui neajuns. Folosind kbhit putem detecta dac se acioneaz vreo tast i se iese din bucl, dar apoi trebuie redat controlul mouse-ului.

- 62 -

Intreruperi definite de utilizator O ntrerupere definit de utilizator este o rutin/funcie care va fi apelat doar n cazul realizrii unei condiii ( de exemplu dac o ntrerupere definit de utilizator este setat utiliznd ntreruperea (0x33,0x0C) s fie apelat cnd mouse-ul este micat). Astfel, cnd mouse-ul este micat, rutina este apelat astfel nct toate operaiile sunt oprite pentru un timp. Pentru a obine starea curent a mouse-ului, AX va lua valoarea 3 i se va apela ntreruperea 0x33. Valoarea lui x va fi returnat n CX, iar valoarea lui y va fi returnat n DX. BX va conine starea butoanelor mouse-ului.

GetMouseStatus(int *b,int *x,int *y) { union REGS i,o; i.x.ax=3; int86(51,&i,&o); *b=o.x.bx; *x=o.x.cx; *y=o.x.dx; return 0; }

Pentru restricionarea mouse-ului la o anumit zon (x1,y1,x2,y2) am folosit urmtoarea funcie :


restrictm(int x1,int y1,int x2,int y2) { union REGS i,o; i.x.ax=7; i.x.cx=x1; i.x.dx=x2; int86(51,&i,&o); i.x.ax=8; i.x.cx=y1; i.x.dx=y2; int86(51,&i,&o); return 0; }

De cele mai multe ori, n aplicaii conteaz dac un buton al mouse-ului a fost acionat sau nu. Pentru a stabili care buton a fost acionat se apeleaz funcia GetMouseStatus(), astfel :
int rclick(void) { int b,x,y; GetMouseStatus(&b,&x,&y); if(b==2) return 0; else return 1; }

//Verificare click stanga

- 63 -

int lclick(void) { int b,x,y; GetMouseStatus(&b,&x,&y); if(b==1) return 0; else return 1; }

Cnd se acioneaz click stnga ntr-o fereastr se va verifica dac acel click s-a realizat pe unul din butoanele existente n fereastra respectiv i, dac da, se va realiza aciunea corespunztoare acelui buton. Fereastra va fi deschis ct timp nu se acioneaz butonul de nchidere, lucru realizat printr-o bucl while. Dac se va aciona butonul stng al mouse-ului pe butonul de nchidere a unei ferestre, se va ascunde pointer-ul mouse-ului, apoi se va terge ecranul. Dac se va aciona butonul stng pe unul din celelalte butoane din fereastr, dup tergerea ecranului se va apela funcia corespunztoare acelui buton.
while(1) if ( lclick_exit(Left,Top,Right,Bottom)) { delay(2000); HideMousePointer(); cleardevice(); break; }

Ascunderea, respectiv afiarea pointer-ului mouse-ului se vor realiza astfel :


// Ascunderea cursorului HideMousePointer() { union REGS i,o; i.x.ax=2; int86(0x33,&i,&o); return 0; }

La deschiderea fiecrei ferestre se va afia cursorul mouse-ului.


//afiarea cursorului ShowMousePointer() { union REGS i,o; i.x.ax=1; int86(0x33,&i,&o); return 0; }

- 64 -

5. Concluzii

Aa cum n antichitate nu se putea face coal fr s se acorde o importan special studiului filosofiei, azi este imposibil s se ignore tehnologia informaiei, respectiv informatica. Sarcina important a profesorului de informatic este aceea c trebuie s gseasc modalitatea de a educa i instrui tnra generaie astfel nct elevii s fie capabili s-i formeze o viziune asupra lumii n mod corespunztor. Orice educator contient de rolul i importana misiunii sale dorete s realizeze o instruire eficient. Aceasta se realizeaz valorificnd ct mai bine rezultatele cercetrii psihopedagogice ntr-o manier coerent, bine gndit i corect realizat. Pe de alt parte, nu este posibil instruirea eficient dac se ignor faptul c ea se produce pe baza unor mecanisme naturale de nvare. A instrui eficient nseamn de fapt a dirija mecanismele interne ale nvrii n direcia competenelor stabilite. Societatea informaional ateapt de la membrii si nu doar cunoaterea utilizrii calculatorului, ci i un comportament curajos, dinamic, deschis i flexibil. Cultura informatic (Computer Literacy) trebuie s devin parte integrant din cultura general. La finalul predrii structurii de date de tip list , elevii vor fi capabili s : poat defini o structur de date de tip list liniar; cunoasc i s foloseasc n aplicaii principalele operaii care se pot efectua cu nodurile (elementele) unei liste liniare; identifice situaiile n care este recomandabil utilizarea acestei structuri de date; foloseasc n mod optim, n aplicaii, liste liniare. Metodele i procedeele didactice impuse de specificul disciplinei sunt metode active, precum : conversaia frontal i individual, explicaia, metoda analitic, munca independent, nvarea prin descoperire, problematizarea etc. n cadrul activitilor practice din laboratorul de informatic pot fi incluse probleme mai - 65 -

complicate din punctul de vedere al cerinelor de rezolvare i de prezentare ctre utilizator a rezultatelor dect exerciiile date pentru fixarea noiunilor. Realizarea proiectelor n cadrul activitilor practice urmresc dezvoltarea abilitilor de lucru n echip i a spiritului competitiv. n acest sens, la lista liniar implementat cu tipul tablou i la lista liniar dublu nlnuit am propus un model de aplicaie practic n care clasa este mprit n grupe de cte doi - trei elevi, fiecare grup primind ca subiect cte o operaie specific listei liniare. n sarcinile profesorului intr i cutarea metodelor adecvate de predare, care s asigure atingerea obiectivelor generale ale disciplinei, precum i antrenarea elevilor n activiti care s ofere anse de a obine succesul colar fr de care ei nu vor avea resurse spirituale i morale pentru a lucra ncreztori n propriile fore. Pachetul de programe LinearList este un model de soft educaional care permite elevilor instruirea asistat de calculator pe tot parcursul leciilor referitoare la lista liniar simplu nlnuit. Soft-ul este folosit pentru ilustrarea formei listei liniare i a operaiilor care se pot executa cu acest tip de structur de date. Aplicaia LinearList a fost realizat din dorina de a veni n sprijinul elevilor care studiaz aceast structur de date. Acest pachet de programe se poate folosi la ,,desenarea" operaiilor cu o list liniar nlnuit i are ca scop familiarizarea elevilor cu structura de tip list liniar i formarea priceperilor i deprinderilor de a realiza programe n care se utilizeaz aceast structur de date. n instruirea asistat, calculatorul nu numai c transmite un mesaj informaional, dar el poate mijloci formarea i consolidarea unor metode de lucru, de nvare. Se poate afirma c nvarea asistat de calculator nu numai c nva elevul, dar l nva i cum s nvee. Prin aplicarea acestei metode de nvare nu se ntrevede diminuarea rolului profesorului. Dimpotriv, sarcinile lui se amplific prin faptul c va trebui s elaboreze programe i s le adapteze la cerinele procesului educativ. Orict de complete ar fi programele de nvare asistat de calculator, profesorul rmne cea mai perfecionat main de nvat. Ceea ce va trebui s tie un absolvent mine, trebuie s tie s-l nvee profesorul su azi.

ANEXA 1
- 66 -

Proiect didactic. Crearea listelor liniare simplu nlnuite Obiectul: Limbajul C Clasa: a XI-a Data: Subiectul: Liste liniare simplu nlnuite n C Tipul leiei: Combinat. Scopul leciei: nsuirea de noi cunotine privind listele liniare simplu nlnuite n C. Obiective operaionale: 1. Elevul s poat defini o structur de date de tip list liniar simplu nlnuit. 2. Elevul s cunoasc i s integreze n aplicaii principalele operaii care se pot efectua cu nodurile (elementele) unei liste liniare simplu nlnuite. 3. Elevul s identifice situaiile n care este recomandat utilizarea acestei structuri de date. Materialul didactic: calculatorul, tabla. Planul de lecie Etapa (timpul) 1.Pregtirea clasei pentru. lecie. 2 min. 2. Verificarea leciei precedente. 15 min. Activitatea desfurat (Profesor + elevi) Metoda i modul de organizare -elevii pun caietele i crile pe banc i se asigur linitea n Activitate clas. comun -elevul de serviciu spune absenii i se trec absenele n catalog, de ctre profesor. -verificarea temelor pt. acas ( pentru elevii x, y, z) -se cere elevului x s defineasc noiunea de pointer -elevul x rspunde: Pointer-ii sunt variabile a cror valoare este interpretat ca adres a unei locaii de memorie unde poate fi accesat o valoare de tipul declarat al pointer-ului. -se cere elevului y s spun cum se realizeaz alocarea dinamic i eliberarea zonelor de memorie n C -elevul y rspunde : n limbajul C, alocarea dinamic se realizeaz prin diversele variante ale funciei malloc(), iar eliberarea zonelor alocate se face prin apelul funciei free(). - profesorul prezint situaiile n care se pot folosi n aplicaii : tablouri, liste liniare implementate cu ajutorul tipului tablou, liste liniare alocate simplu nlnuit. Dac se cunoate dimensiunea tabloului (volumul de date) la momentul elaborrii programului, se recomand folosirea unui tablou cu dimensiunea fix n fiierul surs (eventual n fiierul surs sau ntr-un fiier header se definete cu directiva define dimensiunea tabloului, astfel nct, dac se dorete o versiune a aplicaiei care s permit un volum diferit de date, se modific definiia). - 67 Interogare frontal. Conversaia frontal.

3.Pregtirea leciei noi. 5 min.

Conversaia frontal

Dac se cunoate volumul de date abia la nceputul execuiei programului (pentru fiecare execuie volumul de date este posibil s difere), este indicat folosirea unui tablou pentru care se aloc spaiu n mod dinamic i accesul la elementele tabloului se va face de regul prin pointeri. Ce se ntmpl ns cnd volumul de date nu se cunoate nici mcar la nceputul execuiei, ci doar la sfritul fazei de creare/citire a datelor? Soluia care se recomand a fi folosit n acest caz este urmtoarea : datele se vor implementa sub form de list liniar simplu nlnuit. 4.Predarea noilor cunotine. 15 min. - profesorul prezint forma listei liniare simplu nlnuit. Expunerea O list liniar simplu nlnuit este o structur de forma: Activitate comun.

unde - fiecare nod al listei este legat de nodul urmtor prin intermediul cmpului urm, - p este o variabil pointer care indic primul nod al listei, - info reprezint informaiile coninute de noduri. Fiecare element va conine o zon pentru informaii i cmpul urm. Ultimul element va conine n cmpul urm, NULL. - profesorul definete structura de date de tip list liniar simplu nlnuit n C Structura de date care definete implementarea unei liste liniare simplu nlnuit n C se va defini ca o structur de date recursiv si presupunem c n zona destinat informaiei vom avea un cmp-cheie pentru identificarea nodului n list, iar restul cmpurilor din cadrul listei vor conine informaia propriu-zis, i presupunem c acest cmp-cheie este de tip ntreg, iar cmpul destinat informaiei este de maxim 10 caractere.

- 68 -

Lista poate fi definit n acest caz ca o structur (recursiv) de tipul:


struct nod { int cheie; char info[10] struct nod* urm; } typedef struct nod Tnod; typedef Tnod* ref;

Pentru a efectua orice operaie asupra unei structuri de date, trebuie ca nainte s fie iniializat. Iniializarea se face prin crearea primului nod al listei care presupune generarea unei locaii de memorie de aceeai structur cu nodurile listei i reinerea acestei adrese ntr-o variabil q.

Funcia C care ralizeaz crearea primului nod este :


void ins_p(void) { q = malloc(sizeof(Tnod)); //1 printf("cheia : "); scanf("%d", >cheie); //2 printf("informatia : ");fflush(stdin); scanf("%s",q->info); //2 q->urm = NULL; //3 p = q; //4 }

&q-

- profesorul : Sunt mai multe tehnici de creare a listelor liniare simplu nlnuite : 1. Adugnd nodul curent n faa listei. 2. Cu inserare n spatele listei. 1. Inserarea n faa listei presupune efectuarea urmtorilor pai: se aloc spaiu pentru noua nregistrare, se completeaz informaia (cmpurile info si cheia ), iar adresa urmtoare este cea din p, deci a primului element al listei. Variabila p va memora apoi adresa noii nregistrri.

- 69 -

Funcia care realizeaz inserarea n faa listei este:


void ins_cf(void) { q = (ref)malloc(sizeof(Tnod)); //1 printf("Introduceti cheia nodului : "); fflush(stdin); scanf("%d", &q->cheie); //2 printf("Introduceti informatia utila : "); fflush(stdin); scanf("%s", q->info); //2 q->urm = p; //3 p = q; //4 }

2. Inserarea la sfritul listei. Aceast funcie se redacteaz mai simplu dac se cunoate locaia ultimului nod al listei. Teoretic, acest lucru nu prezint nici o dificultate deoarece se poate parcurge lista de la nceputul ei indicat prin p, pn la detectarea nodului care are cmpul urm==NULL. n practic, aceast soluie nu este convenabil deoarece parcurgerea ntregii liste este ineficient. Se prefer s se lucreze cu o variabil pointer ajuttoare q care indic mereu ultimul nod al listei, dup cum p indic primul nod al listei.

void incs (void) { r = (ref)malloc(sizeof(Tnod));//1 printf("Introduceti cheia nodului : "); fflush(stdin); scanf("%d", &r->cheie); //2 printf("Introduceti informatia utila : "); fflush(stdin); scanf("%s", r->info);//2 r->urm=NULL;//3 q->urm = r; //4 q = r;//5 }

Traversarea unei liste nlnuite Prin traversarea unei liste se nelege executarea unei - 70 -

anumite operaii asupra tuturor nodurilor listei. Fie p pointer-ul care indic primul nod al listei i fie r o variabil pointer auxiliar. Atunci, funcia care realizeaz listarea elementelor listei va fi urmtoarea:
void listare(void) { r = p; while(r!=NULL) { printf("Cheia = %d", r->cheie); printf("Informatia = %s", r->info); printf("\n"); r = r->urm; } }

5.Fixarea cunotinelor 10 min.

profesorul prezint un exemplu de creare a listei liniare simplu nlnuite. S se creeze lista liniar simplu nlnuit cu inserare n fa. Operaiile care se vor realiza asupra listei sunt : * Creare. n probleme, de obicei, nu se cunoate de la nceput numrul de elemente al listei. nregistrrile se vor aduga prin apelul funciei ins_fa, care va fi apelat de fiecare dat cnd utilizatorul dorete adugarea unei noi nregistrri n list. *Listare. Atta timp ct nu am ajuns la sfritul listei, tiprim informaia util i trecem la nregistrarea urmtoare. * Prin intermediul funciei meniu() se va specifica tipul operaiei ce se dorete s se efectueze asupra listei.
#include <stdio.h> #include <stdlib.h> #include <ctype.h> /*pt functia malloc*/ /*pt functia toupper*/

Rezolvare de probleme + Conversaia

typedef struct nod { int cheie; /*cheia dupa care are loc identificarea nodurilor in cadrul listei*/ char info[10]; /*informatia utila din cadrul listei*/ struct nod *urm; /*un pointer catre urmatorul nod din lista*/ }Tnod; typedef Tnod* ref; /*referinta catre o structura de tipul Tnod*/ ref /*p q r p=NULL, q=NULL, r=NULL; - pointer catre primul nod din lista pointer catre ultimul nod din lista pointer auxiliar*/

- 71 -

void meniu(void); void ins_fata(void); void listare(void); void creare(void); void creare() /*Creaza lista prin apeluri succesive ale functiei ins_fata*/ { char c; do { ins_fata(); printf("Continuati(D/N) : "); fflush(stdin); scanf("%c", &c); c = toupper(c); } while(c=='D'); }/*sfarsit creare*/ void ins_fata(void) /*insereaza un nod in fata unei listei liniare simplu nlnuit*/ { r = (ref)malloc(sizeof(Tnod)); printf("Introduceti cheia nodului : "); fflush(stdin);scanf("%d",&r->cheie); printf("Introduceti informatia utila : "); fflush(stdin); scanf("%s", r->info); r->urm = p; p = r; }/*sfarsit ins_fata*/ void listare(void) /*listeaza elementele l.l.s.i. cu inserare in fata*/ { if(p==NULL) printf("Lista este vida!\n"); else { printf("Elementele listei sunt :\n"); r = p; while(r!=NULL) { printf("Cheia = %d ", r->cheie); printf("Informatia = %s", r->info); printf("\n"); r = r->urm; } } }/*sfarsit listare*/

6.Tema pentru acas. 3 min.

1. Completai programul prezentat mai sus cu funciile meniu() i main(). 2. S se creeze i s se afieze lista liniar simplu nlnuit cu inserare n spatele listei. Elevii x i z urmeaz s fie notai dup completri din leciile urmtoare.

- 72 -

ANEXA 2
Proiect didactic. Operaii asupra listelor liniare simplu nlnuite. Obiectul: Limbajul C Clasa: a XI-a Data: Subiectul: Liste liniare simplu nlnuite n C Tipul leiei: Combinat. Scopul leciei: nsuirea de noi cunotine privind listele liniare simplu nlnuite n C. Obiective operaionale: 1. Elevul s poat defini o structur de date de tip list liniar simplu nlnuit. 2. Elevul s cunoasc i s integreze n aplicaii principalele operaii care se pot efectua cu nodurile (elementele) unei liste liniare simplu nlnuite. 3. Elevul s identifice situaiile n care este recomandat utilizarea acestei structuri de date. Materialul didactic: calculatorul, tabla. Planul de lecie Etapa (timpul) Metoda i modul de organizar e 1.Pregtirea -elevii pun caietele i crile pe banc i se asigur linitea n Activitate clasei pentru clas. comun lecie. -elevul de serviciu spune absenii i se trec absenele n catalog, 2 min. de ctre profesor. - 73 Activitatea desfurat (Profesor + elevi)

2. Verificarea leciei precedente. 15 min.

-verificarea temelor pentru acas ( pentru elevii x, y, z) Interogare -profesorul cere elevului x s defineasc noiunea list ca i frontal. structur recursiv -elevul x rspunde: ConversaLista poate fi definit ca o structur recursiv de tipul: ia struct nod frontal.
{ int cheie; char info[10] struct nod* urm; struct nod Tnod; Tnod* ref;

} typedef typedef

profesorul cere elevului x s prezinte funcia de inserare a unui nod n faa listei liniare elevul x rspunde

void ins_cf(void) { q = (ref)malloc(sizeof(Tnod)); //1 printf("Introduceti cheia nodului : "); fflush(stdin); scanf("%d", &q->cheie); //2 printf("Introduceti informatia utila : "); fflush(stdin); scanf("%s", q->info); //2 q->urm = p; //3 p = q; //4 } - profesorul cere elevului z s prezinte funcia de inserare

unui nod n spatele listei liniare - elevul y rspunde


void incs (void) { r = (ref)malloc(sizeof(Tnod));//1 printf("Introduceti cheia nodului : "); fflush(stdin); scanf("%d", &r->cheie); //2 printf("Introduceti informatia utila : "); fflush(stdin); scanf("%s", r->info);//2 r->urm=NULL;//3 q->urm = r; //4 q = r;//5 }

3.Pregtirea leciei noi. 5 min. 4.Predarea noilor cunotine. 15 min.

Sunt i situaii cnd se dorete inserarea unui nod n lista Conversaliniar simplu nlnuit dup sau naintea unui nod de cheie ia frontal dat, sau se poate ntmpla s nu mai avem nevoie de un anumit nod din list, caz n care nodul trebuie suprimat. Pentru aceste operaii trebuie s cutm un nod de cheie dat, k, n list. - profesorul prezint operaia de cutare ntr-o list liniar Expunerea simplu nlnuit : void cautare(void) Activitate { comun. int b=0;
r=p; while ((b==0) && (r!=NULL)) if (r->cheie==k ) b=1;

- 74 -

else r=r->urm; }

Operaia de cutare s-ar putea implementa printr-o funcie care nu utilizeaz variabila boolean b.
void cautare(void) { r=p; while((r->cheie!=k && r!=NULL)) r=r->urm; }

n acest caz, la sfritul execuiei funciei, r va conine adresa nodului cu cheia dat, dac acesta exist n list, sau NULL, dac acesta nu exist n list. n ultimul caz ,nu are sens operaia r->cheie, astfel nct n funcia imlementat putem avea eroare sau nu. Urmtoarea variant a funciei de cutare este corect :
int cautare(int k) { r = p; while((r!=NULL) && (r->cheie!=k)) r = r->urm; if(r==NULL) return -1; /*returneaza -1 daca nu a gasit un nod cu cheia k*/ else return 1; /*returneaza 1 daca a gasit un nod cu cheia k*/ }

n cazul n care cutarea se termin fr a gsi elementul de cheie k, deci se termin pentru c s-a ajuns la sfritul listei (r==NULL) atunci nodul cu cheia k nu exist n list i se returneaz -1. Dac ns r este diferit de NULL, nseamn c nodul cu cheia k a fost gsit, r va conine adresa nodului de cheie k, i se returneaz 1. - profesorul prezint tehnicile de inserie a unui nod ntr-un loc oarecare al listei liniare simplu nlnuite. Inseria unui nod ntr-un loc oarecare al listei se poate face nainte sau dup un nod anume. Dup un nod anume. Fie r un pointer care indic un nod oarecare al listei i s o variabil pointer ajuttoare. n aceste condiii, inseria unui nod dup nodul r se realizeaz astfel: se aloc spatiu pentru noul nod, se completeaza informaia (cmpurile cheia si info) pentru noul nod, i se face legtura cu nodul urmtor, apoi cu nodul precedent.
void insd(void)

- 75 -

{ s = (ref)malloc(sizeof(Tnod)); //1 printf("Introduceti cheia nodului : "); fflush(stdin); scanf("%d", &s->cheie); //2 printf("Introduceti informatia utila : "); fflush(stdin); scanf("%s", s->info); //2 s->urm = r->urm;// 3 - se realizeaz

legtura cu nodul urmtor r->urm=s;// 4 - se realizeaz legtura cu nodul precedent


}

naintea unui nod. Dac se dorete inseria noului nod n lista liniar naintea unui nod indicat r, apare o complicaie generat de imposibilitatea practic de a afla simplu adresa predecesorului nodului r. Dup cum s-a precizat deja, n practic nu se admite parcurgerea de la nceput a listei pentru aflarea adresei nodului respectiv. Aceast problem se poate rezolva simplu cu ajutorul urmtoarei tehnici: se insereaz un nod dup nodul r, se asigneaz acest nod cu r, dup care se creeaz cmpurile cheie i info pentru nod i se asigneaz cu ele cmpurile corespunztoare ale vechiului nod r.
void insi(void) { s = (ref)malloc(sizeof(Tnod));//1 s=r;//2 r->urm = s;//3 printf("Introduceti cheia nodului : "); fflush(stdin); scanf("%d", &r->cheie); //4 printf("Introduceti informatia utila : "); fflush(stdin); scanf("%s", r->info);//4 }

- 76 -

5.Fixarea cunotinelor 10 min.

- profesorul cere elevilor s creeze o list liniar simplu nlnuit i s efectueze asupra sa operaiile prezentate S se completeze programul de creare a listei liniare simplu nlnuite cu inserare n fa cu crearea separat a primului nod, cu operaiile de cutare i de inserare a unui nod. Funciile folosite n program sunt : * Creare. n probleme, de obicei, nu se cunoate de la nceput numrul de elemente al listei. nregistrrile se vor aduga prin apelul funciei ins_fa, care va fi apelat de fiecare dat cnd utilizatorul dorete adugarea unei noi nregistrri n list. *Listare. Atta timp ct nu am ajuns la sfritul listei, tiprim informaia util i trecem la nregistrarea urmtoare. *Inserare. Se solicit introducerea nodului dup care/naintea cruia se realizeaz inserarea. Dac nodul nu exist n list se va semnala acest lucru. Dac ns nodul a fost gsit, se va trece la inserarea elementului. * Prin intermediul funciei meniu() se va specifica tipul operaiei ce se dorete s se efectueze asupra listei.. S se creeze i s se afieze lista liniar simplu nlnuit cu inserare n spatele listei i s se efectueze asupra sa operaiile de cutare i inserare a unui nod ntr-un anumit loc din list.. Se noteaz elevii x i y, se anun nota i se trece n catalog i carnet.

Rezolvarea de probleme + conversaia

6.Tema pentru acas. 3 min.

- 77 -

Bibliografie
1. Popovici Paraschiva Structuri de date liniare i arborescente, Editura Eubeea, Timioara, 2002. 2. Masalagiu Cristian, Asiminoaei Ioan Didactica predrii informaticii, Editura Polirom, Iai, 2004. 3. I. Rus, D. Varna Metodica predrii matematicii, Editura Didactic i Pedagogic, Bucureti, 1983 4. Tenenbaum Aaron, Langsam Yedidyah, Augenstein Moshe Data Structures Using C, Prentice-Hall.Inc, 1990 5. Kernighan W. Brian, Ritchie M. Dennis - The C programming Language, PrenticeHall, 1988 6. Oprescu Daniela Informatic, manual pentru clasa a X-a , Editura Niculescu ABC, 2004 7. Tudor Sorin Tehnici de programare.Manual pentru clasa a X-a, Editura L&S, 1996 8. Munteanu Fl., Ionescu T., Musc Gh., Saru Daniela, Dasclu S.M. Programarea calculatoarelor. Manual pentru licee de informatic, clasele X-XII, Editura Didactic i Pedagogic, Bucureti, 1995

- 78 -

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