840 likes | 1.98k Views
Colegiul Na ţ ional de Informatic ă “Spiru Haret” Suceava. Liste simplu înlănţuite alocate dinamic. Liste simplu înlănţuite alocate dinamic. profesor Gabriela – Rodica Freitag. Cuprins:. Noţiun ile de pointer şi variabilă dinamică Structuri de date Lista. Definiţie. Declarare
E N D
Colegiul Naţional de Informatică “Spiru Haret” Suceava Liste simplu înlănţuite alocate dinamic Liste simplu înlănţuite alocate dinamic profesor Gabriela – Rodica Freitag
Cuprins: • Noţiunile de pointer şivariabilă dinamică • Structuri de date • Lista. Definiţie. Declarare • Operaţii cu liste simplu înlănţuite • Aplicaţii
Noţiunile de pointer şi variabilă dinamică Alocarea dinamică este metoda prin care unei variabile de memorie sau unei structuri de date i se alocă spaţiu sau se eliberează spaţiul de memorie ocupat de ea în timpul execuţiei programului, în funcţie de necesităţi. Variabilele care folosesc alocarea dinamică se numesc variabile dinamice. Variabilele dinamice nu se declară, nu au nume şi se folosesc în program prin intermediul variabilelor de tip pointer alocate static. Ovariabilă de tip pointer se caracterizează prin faptul că valorile pe care le poate memora sunt adrese de memorie. Declarare: tip * nume unde: tip - tipul datei socată la adresa indicată de pointer * - operatorul de referinţă nume - numele variabilei de tip pointer În momentul în care în program trebuie folosită o variabilă dinamică, se cere sistemului să i se aloce spaţiu în HEAP. Pentru alocare se foloseşte operatorul new: nume=new tip; iar pentru eliberarea spaţiului de memorie alocat în Heap se foloseşte operatorul delete: delete nume; cuprins
Structuri de date • Structura de date este o noţiune abstractă, prin care se înţelege un ansamblu de date caracterizat prin relaţiile existente între ele şi a operaţiilor care pot fi efectuate cu datele respective. • Clasificarea structurilor de date se poate face în funcţie de: • tipul datelor • - structuri de date omogene, adică toate datelecomponente sunt deacelaşitip (ex. tabloul) • structuri de date neomogene, adică pot conţine date de tipuri diferite(ex. înregistrare). • alocarea memoriei: • - static - structura de date ocupă o zonă de memorie de dimensiune fixă,alocată pe întreaga durată a execuţiei blocului în care este declarată. • - dinamic - structura de date ocupă o zonă de memoriede dimensiune variabilă, alocată pe parcursul execuţiei programului la cererea explicităa programatorului. cuprins
Lista Definiţii Există următoarele tipuri de liste: lista liniară simplu înlănţuită - legăturile între noduri sunt liniare şi într-un singur sens. lista liniară dublu înlănţuită – fiecare nod este legat prin pointeri atât de nodul anterior, cât şi de nodul următor. lista circulară – ultimul nod adresează primul nod. Noduleste o unitate de informaţie elementară care poate conţine informaţii utile şi date de legătură. Listaeste o structură de date constituită dintr-o succesiune de elemente,numite noduri, aflate într-o relaţie de ordine. Declararea listei înlănţuite info – va conţine informaţia utilă memorată în nodul curent. Tipul acestui câmp poate fi orice tip C++. urm - câmp ce reţine adresa nodului următor (sau ant – adresa nodului anterior). struct nod{ tip info; nod *urm(*ant); }; nod *prim, *ultim; • crearea primului nod (iniţializarea listei) • inserarea unui element într-o listă • extragerea unui element dintr-o listă • accesarea unui element dintr-o listă • afişarea elementelor unei liste Operaţiile elementare cuprins
… info1 adr2 info2 adr3 infon-2 adrn-1 infon-1 adrn infon NULL adr1 adr2 adrn-2 adrn-1 adrn Operaţiile elementare care se pot executa asupra uneiliste liniare simplu înlănţuite: Lista liniară simplu înlănţuită O listă liniară simplu înlănţuită este o structură de forma: • 1.Creareaprimului nod • 2. Inserareaunui nod • adăugarea unui nod la începutul listei • adăugarea unui nod la sfârşitul listei • inserarea unui nod înaintea unui anumit nod din listă • inserarea unui nod după un anumit nod din listă • 3. Ştergereaunui nod • ştergerea primului nod din listă • ştergerea ultimului nod din listă • ştergerea unui anumit nod din • listă • 4. Căutarea unui element în listă • 5. Afişareaelementelor listei cuprins
Lista liniară simplu înlănţuită Crearea unei liste liniare simplu înlănţuite info NULL prim , ultim void creare(nod *&prim, nod *&ultim) { prim=new nod; cin>>priminfo; primurm=NULL; ultim=prim; } • se alocă spaţiu de memorie în zona HEAP • prim=new nod; • se completează informaţia utilă din noul nod creat • cin>>priminfo; • se completează câmpul urm cu valoarea NULL, deoarece nodul este unic în listă • primurm=NULL; • se păstrează valoarea variabilei prim şi în variabila ultim • ultim=prim; • se alocă spaţiu de memorie în zona HEAP • prim=new nod; • se completează informaţia utilă din noul nod creat • cin>>priminfo; • se completează câmpul urm cu valoarea NULL, deoarece nodul este unic în listă • primurm=NULL; • se păstrează valoarea variabilei prim şi în variabila ultim • ultim=prim; | initializare LSI| | adăugare la inceput| | adăugare la sfârşit| | inserare inaintea unui nod| | inserare după un nod| | ştergerea primului nod| | ştergerea ultimului nod| | ştergerea unui nod| | căutarea unui nod| | afişarea LSI| cuprins
Lista liniară simplu înlănţuită Adăugarea unui nod la începutul listei • se alocă memorie în zona HEAP • p=new nod; • se citeşte informaţia utilă din noul nod • cin>>pinfo; • se leagă nodul creat in faţa primului nod al listei • purm=prim; • se modifică adresa primului nod al listei prim=p; void adăugare_inc ( nod *&prim) { nod *p=new nod; cin>>pinfo; purm=prim; prim=p; } DEMO | initializare LSI| | adăugare la inceput| | adăugare la sfârşit| | inserare inaintea unui nod| | inserare după un nod| | ştergerea primului nod| | ştergerea ultimului nod| | ştergerea unui nod| | căutarea unui nod| | afişarea LSI| cuprins
Lista liniară simplu înlănţuită Adăugarea nodului cu informaţia 4 la începutul listei adr1 1 adr2 2 adr3 3 NULL 4 adr1 adr2 adr3 p prim prim • se alocă memorie în zona HEAP p=new nod; • se citeşte informaţia utilă din noul nod cin>>pinfo; • se leagă nodul creat in faţa primului nod al listei • purm=prim; • se modifică adresa primului nod al listei prim=p; void adaugare_inc ( nod *&prim) { nod *p=new nod; cin>>pinfo; purm=prim; prim=p; } | initializare LSI| | adăugare la inceput| | adăugare la sfârşit| | inserare inaintea unui nod| | inserare după un nod| | ştergerea primului nod| | ştergerea ultimului nod| | ştergerea unui nod| | căutarea unui nod| | afişarea LSI| cuprins
Lista liniară simplu înlănţuită Adăugarea unui nod la sfârşitul listei • se alocă spaţiu de memorie în zona HEAP • p=new nod; • se completează informaţia utilă din noul nod creat cin>>pinfo; • se completează câmpul urm cu valoarea NULL, deoarece nodul nou este ultimulîn listă purm=NULL; • se leagăde listă noul nod • ultimurm=p; • se modifică adresa ultimului nod • ultim=p; void adăugare_sf ( nod*&ultim) { nod *p=new nod; cin>>pinfo; purm=NULL; ultimurm=p; ultim=p; } DEMO
| initializare LSI| | adăugare la inceput| | adăugare la sfârşit| | inserare inaintea unui nod| | inserare după un nod| | ştergerea primului nod| | ştergerea ultimului nod| | ştergerea unui nod| | căutarea unui nod| | afişarea LSI| Lista liniară simplu înlănţuită Adăugarea nodului cu informaţia 4 la sfârşitul listei p 1 adr2 2 adr3 3 4 NULL NULL adr3 adr2 p prim ultim ultim • se alocă spaţiu de memorie în zona HEAP • p=new nod; • se completează informaţia utilă din noul nod cin>>pinfo; • se completează câmpul urm cu valoarea NULL, deoarece nodul nou este ultimul în listă purm=NULL; • se leagăde listă noul nod • ultimurm=p; • se modifică adresa ultimului nod • ultim=p; void adăugare_sf ( nod*&ultim) { nod *p=new nod; cin>>pinfo; purm=NULL; ultimurm=p; ultim=p; } cuprins
Lista liniară simplu înlănţuită Inserarea unui nod după nodulce are memorat în câmpul infovaloarea k • se alocă spaţiu de memorie în zona HEAP • p=new nod; • se completează informaţia utilă din noul nod creat • cin>>pinfo; • se va căuta în listă nodul ce conţine în câmpul info valoarea k (fie q adresa acestui nod) şi se va crea legatura intre listă şi noul nod • purm=qurm; • qurm=p; DEMO • voidins_după (nod *prim, int k) • { nod *p=new nod; • cin>>pinfo; • nod *q=prim; • while (qinfo!=k) • q=qurm; • purm=qurm; • qurm=p; • }
Lista liniară simplu înlănţuită Inserarea nodului cu informaţia 4 după nodul a cărui informaţie este 2 • se alocă spaţiu de memorie în zona HEAP • p=new nod; • se completează informaţia utilă din noul nod creat • cin>>pinfo; • se va căuta în listă nodul ce conţine în câmpul info valoarea k (fie q adresa acestui nod) • se va crea legatura intre listă şi noul nod • purm=qurm; • qurm=p; 1 adr2 2 adr3 p 3 NULL adr1 prim ultim q 4 adr3 p • voidins_după (nod *prim, int k) • { nod *p=new nod; • cin>>pinfo; • nod *q=prim; • while (qinfo!=k) • q=qurm; • purm=qurm; • qurm=p; • } | initializare LSI| | adăugare la inceput| | adăugare la sfârşit| | inserare inaintea unui nod| | inserare după un nod| | ştergerea primului nod| | ştergerea ultimului nod| | ştergerea unui nod| | căutarea unui nod| | afişarea LSI| cuprins
Lista liniară simplu înlănţuită Inserarea unui nod înainteanoduluice are memorat în câmpul infovaloarea k • se alocă spaţiu de memorie în zona HEAP pentru noul nod • p=new nod; • se completează informaţia utilă din noul nod • cin>>pinfo; • se va căuta în listă nodul anterior celui ce conţine în câmpul info valoarea k (fie q adresa acestuinod) şi se va crea legatura intre listă şi noul nod • purm=qurm; • qurm=p; • void ins_înainte ( nod *&prim, int k ) • { nod *p=new nod; • cin>>pinfo; • if(priminfo==k) • { purm=prim; • prim=p; • } • else • { nod *q=prim; • while(qurm info!=k) • q=qurm; • purm=qurm; • qurm=p; • } • } DEMO
Lista liniară simplu înlănţuită Inserarea nodului cu informaţia 4 înainte de nodul a cărui informaţie este 2 1 p 2 adr3 3 adr1 adr2 NULL adr3 adr2 prim ultim q • void ins_înainte ( nod *&prim, int k ) • { nod *p=new nod; • cin>>pinfo; • if(priminfo==k) • { purm=prim; • prim=p; • } • else • { nod *q=prim; • while(qurm info!=k) • q=qurm; • purm=qurm; • qurm=p; • } • } 4 adr2 p • se alocă spaţiu de memorie în zona HEAP pentru noul nod • p=new nod; • se completează informaţia utilă din noul nod • cin>>pinfo; • se va căuta în listă nodul anterior celui ce conţine în câmpul info valoarea k (fie q adresa acestui nod) • se va crea legatura intre listă şi noul nod • purm=qurm; • qurm=p; | initializare LSI| | adăugare la inceput| | adăugare la sfârşit| | inserare inaintea unui nod| | inserare după un nod| | ştergerea primului nod| | ştergerea ultimului nod| | ştergerea unui nod| | căutarea unui nod| | afişarea LSI| cuprins
Lista liniară simplu înlănţuită Ştergerea primului nod p 1 adr2 2 adr3 3 ultim NULL 4 adr2 adr3 prim prim ultim • se reţine adresa primului nod în pointerul p • p=prim; • se modifică adresa primului nod cu adresa nodului urmator • prim=purm; • se şterge efectiv primul nod adresat de p eliberând memoria ocupată • delete p; void şterg_prim (nod *&prim) { nod * p=prim; prim=purm; delete p; } | initializare LSI| | adăugare la inceput| | adăugare la sfârşit| | inserare inaintea unui nod| | inserare după un nod| | ştergerea primului nod| | ştergerea ultimului nod| | ştergerea unui nod| | căutarea unui nod| | afişarea LSI| cuprins
Lista liniară simplu înlănţuită Ştergerea ultimului nod 1 adr2 2 adr3 3 ultim 4 NULL NULL adr3 adr2 p p p prim ultim ultim • se mută pointerul p de la primul la penultimul nod • p=prim; • while (purm!=ultim) • p=purm; • se şterge fizic ultimul nod • delete ultim; • se completeazăcâmpul de adresă al penultimului nod cuvaloareaNULL, deoarece nodul p este acum ultimul nod din listă • purm=NULL; • se modifică pointerul ultim cu adresa ultimului nod ultim=p; voidşterg_ultim ( nod *&ultim) { nod *p=prim; while (purm!=ultim) p=purm; delete ultim; purm=NULL; ultim=p; } | initializare LSI| | adăugare la inceput| | adăugare la sfârşit| | inserare inaintea unui nod| | inserare după un nod| | ştergerea primului nod| | ştergerea ultimului nod| | ştergerea unui nod| | căutarea unui nod| | afişarea LSI| cuprins
Lista liniară simplu înlănţuită Ştergerea nodului cu informaţia 2 din listă 1 adr2 2 adr3 3 ultim 4 NULL adr3 adr3 adr2 ultim prim p q • fie q adresa nodului anterior celui de şters, transmisă prin parametru • se obţine adresa nodului de şters p=qurm; • se leagă nodul q de nodul următor nodului de şters qurm=purm; • se şterge efectiv nodul de la adresa p delete p; voidşterg_nod ( nod *q ) { nod *p=qurm; qurm=purm; delete p; } | initializare LSI| | adăugare la inceput| | adăugare la sfârşit| | inserare inaintea unui nod| | inserare după un nod| | ştergerea primului nod| | ştergerea ultimului nod| | ştergerea unui nod| | căutarea unui nod| | afişarea LSI| cuprins
NULL Lista liniară simplu înlănţuită Afişarea nodurilor listei info1 adr2 info2 adr3 infon-2 adrn-1 infon-1 adrn infon ... adr1 adr2 adrn-2 adrn-1 adrn • se pleacă de la primul nod al listeisalvându-se adresa lui în variabila p • cât timp nu s-a ajuns la ultimul nod al listei execută • - se afişează informaţia din nodul curent • - se trece la următorul nod din listă voidafişare ( nod *prim ) { nod *p=prim; while(p!=NULL) { cout<<pinfo; p=purm; } } | initializare LSI| | adăugare la inceput| | adăugare la sfârşit| | inserare inaintea unui nod| | inserare după un nod| | ştergerea primului nod| | ştergerea ultimului nod| | ştergerea unui nod| | căutarea unui nod| | afişarea LSI| cuprins
NULL Lista liniară simplu înlănţuită Căutarea nodului ce conţine în câmpul info valoarea reţinută în variabila x info1 adr2 info2 adr3 ... infon-2 adrn-1 infon infon-1 adrn adr1 adr2 adrn-2 adrn-1 adrn • se citeşte în variabila x informaţia pe care o căutăm • se parcurge lista de la primul nod către ultimul comparându-se de fiecare dată x cu informaţia din nodul curent • funcţia căutare va returna adresa primului nod cu informaţia x din listă sau NULL dacă nu există un astfel de nod nod *căutare(nod *prim) { int x; cin>>x; nod *p=prim; while(p!=NULL && pinfo!=x) p=purm; return p; } | initializare LSI| | adăugare la inceput| | adăugare la sfârşit| | inserare inaintea unui nod| | inserare după un nod| | ştergerea primului nod| | ştergerea ultimului nod| | ştergerea unui nod| | căutarea unui nod| | afişarea LSI| cuprins
Lista liniară simplu înlănţuită. Aplicaţii 1. Se citesc dintr-un fişier text numere naturale. Se cere afişarea acestora în ordine crescătoare folosind sortarea prin inserţie. Ideea de bază a metodei constă în a considera primele valori sortate, urmând să inserăm valoarea curentă citită din fişier în şirul deja sortat. Prin utilizarea listelor înlănţuite, inserţia este mai simplă întrucât nu necesită deplasarea componentelor ca în cazul vectorilor. cuprins >>>
Lista liniară simplu înlănţuită. Aplicaţii 2. Se citesc dintr-un fişier text numere naturale. Se cere să se creeze o listă simplu înlănţuită, iar apoi să se inverseze legăturile dintre noduri. După inversarea legăturilor, primul nod va deveni ultimul, al doilea nod al listei iniţiale va indica spre primul, al treilea către al doilea, etc.. Vom utiliza trei pointeri p,q şi r (p adresează primul nod al listei cu legăturile inversate, q, primul nod al listei cu legăturile iniţiale, iar r, nodul următor nodului q). cuprins >>>
Lista liniară simplu înlănţuită. Aplicaţii 3. Fie două polinoame P(x) şi Q(x). Să se afişeze polinomul sumă S(x)=P(x)+Q(x). Fişierul text conţine date referitoare la monoamele celor două polinoame. Polinoamele se memorează cu ajutorul a două liste simplu înlănţuite ordonate descrescător după gradul necunoscutei. Polinomul sumă se obţine folosind algoritmul de interclasare a celor două liste într-o altă listă. Bibliografie >>> cuprins
Bibliografie • George Daniel Mateescu, Informatică pentru liceu şi bacalaureat. Manual clasa a XI-a, ed. Donaris, Sibiu 2006 • Mariana Miloşescu, Informatică intensiv. Manual clasa a XI-a, ed. Didactică şi Pedagogică, Bucureşti 2006 • Dana Lica, Doru Popescu Atanastasiu, Radu Boriga, Fundamentele programării. Culegere de probleme pentru clasele IX-XI, ed. L&S Soft, Bucureşti 2003 • Clara Ionescu, Adina Bălan, Informatică pentru grupele de performanţă, clasa a X-a, ed. Dacia Educaţional, Cluj-Napoca 2004 home