Liste Dublu Inlantuite

Listele dublu inlantuite sunt structuri de date dinamice omogene. Ele au aceleasi caracteristici de baza ca si listele simplu inlantuite. Diferenta fata de acestea consta in faptul ca, pentru fiecare nod, se retine si adresa elementului anterior, ceea ce permite traversarea listei in ambele directii. Lista dublu inlantuita poate fi reprezentata grafic astfel:

1. Structura listei
Structura folosita este similara cu cea de la liste simple. Pentru a asigura un grad mai mare de generalitate listei a fost creat un alias pentru datele utile (in cazul nostru un intreg): // Datele asociate unui // element dintr-o lista typedef int Date; In cazul in care se doreste memorarea unui alt tip de date, trebuie schimbata doar declaratia aliasului Date. Pentru memorarea listei se foloseste o structura autoreferita. Acesta structura va avea forma: // Structura unui element // dintr-o lista dublu inlantuita struct Element {

1

* anterior. 2. pointerul anterior va avea valoarea NULL. }. pointerul urmator al ultimului element va referi primul element al listei. In cazul in care elemenul este ultimul din lista. pointerul urmator va avea valoarea NULL.// datele efective memorate Date valoare. Operatii cu liste duble Principalele operatii cu liste sunt: Parcurgere si afisare lista Lista este parcursa pornind de la pointerul spre primul element si avansand folosind pointerii din structura pana la sfarsitul listei (pointer NULL). Declararea listei se face sub forma: // declarare lista vida Element* cap = NULL. In cazul in care se doreste crearea unei liste circulare. // legatura catre nodul urmator Element* urmator. Pentru primul element. iar pointerul anterior al primului element va referi ultimul element. // Parcurgere si afisare lista dubla void Afisare(Element* cap) { // cat timp mai avem elemente // in lista while (cap != NULL) 2 .

a) Inserare la inceput Acesta este cazul cel mai simplu: trebuie doar alocat elementul. . // avanseaza la elementul urmator cap = cap->urmator. // legare nod in lista 3 . iar avansarea se va face folosind secventa cap = cap->anterior. legat de primul element din lista si repozitionarea capului listei: // Inserare element la inceputul unei // liste dublu inlantuite void InserareInceput(Element* &cap. Inserare element Inserarea unui element se poate face la inceputul sau la sfarsitul listei. elem->valoare = val. } } Pentru parcurgerea inversa a listei se va porni cu un pointer catre ultimul element al listei. Date val) { // Alocare nod si initializare valoare Element *elem = new Element. elem->anterior = NULL.{ // afiseaza elementul curent cout << cap->valoare << endl.

elem->anterior = NULL. if (cap != NULL) cap->anterior = elem. // daca avem lista vida if (cap == NULL) // doar modificam capul listei cap = elem. trebuie avut in vedere cazul in care lista este vida. 4 . elem->urmator = NULL. elem->valoare = val. // Inserare element la sfarsitul unei // liste dublu inlantuite void InserareSfarsit(Element* &cap. // mutarea capului listei cap = elem.elem->urmator = cap. } b) Inserare la sfarsitul listei In acest caz trebuie intai parcursa lista si dupa aceea adaugat elementul si legat de restul listei. De asemenea. Date val) { // Alocare si initializare nod Element *elem = new Element.

elem->valoare = val. elem->anterior = nod. // lista vida if (cap == NULL) { 5 . while (nod->urmator != NULL) nod = nod->urmator.else { // parcurgem lista pana la ultimul nod Element *nod = cap. Element* p. elem->anterior = NULL. Date val) { // Alocare si initializare nod Element *elem = new Element. } } c) inserare dupa un element dat void InserareInterior(Element* &cap. // adaugam elementul nou in lista nod->urmator = elem. elem->urmator = NULL.

} SIRURI DE CARACTERE O constanta de tip sir de caractere de declara intre doua caractere ³. cap->anterior = elem. cap = elem. p->urmator = elem. Conventia este ca ultimul octet sa retina 0 (codul caracterului nul). Trebuie rezervate lungimea_sirului+1 caractere char (+1 pentru caracterul nul). In memoria interna. Caracterul nul este memorat automat. elem->anterior = p. return. } // inserare in interior elem->urmator = p->urmator.cap = elem. } // inserare la inceputul listei if (cap == p) { elem->urmator = cap. return. 6 . o constanta de acest tip este retinuta sub forma unui vector de caractere. p->urmator->anterior = elem. Fiecare componenta a sirului (incepand cu cea de indice 0) retine codul ASCII al caracterului pe care il memoreaza.

cout<<sc1[0]. ¶\0¶}. ¶c¶. // eroare: tablou neinitializat // afiseaza primul caracter din sirul sc1 // afiseaza al treilea element din sirul sc1 // elementului din sir de indice 1 i se atribuie valoarea µK¶. ¶d¶. Exemplu : char vect[11]=´calculator´. ¶e¶}. CITIREA / AFISAREA SIRURILOR DE CARACTERE 7 . // tablou de caractere char sc[5] = {¶a¶. ¶b¶. cout<<sc1[2]. caracterul null. //afiseaza abcd cout<<tc<<endl. char s[10]. deci nu poate fi afisat ca sir cout<<s<<endl. (s-au rezervat mai multi octeti decat era necesar) Sirurile de caractere sunt de fapt tablouri de caractere. char sc1[5] = ´abcd´. ¶b¶. cout<<sc<<endln. ¶c¶. // sir de caractere cu elementele abcd Ultima initializare este echivalenta cu: char sc[5] = ´abcd´. ¶d¶. //sau char sc[] = ´abcd´.Limbajul C/C++ permite initializarea unui tablou de caractere printr-o constanta sir. char vect[]=´calculator´. Exemplu: char tc[5] = {¶a¶. care include automat caracterul null. (compilatorul face calculul numarului de octeti necesari) char vect[100]=´calculator´. sc1[1]=¶K¶. care au ca ultim element un terminator de sir. //eroare: tabloul de caractere nu contine terminatorul de sir.

caracter cu caracter (desi nu este recomandata). Exemplu 8 . daca se citeste ³ora de informatica´. a.Sirurile de caractere pot fi initializate inca de la declarare sau citite pe parcursul programului. n>>c. terminatorul de sir nu este memorat automat. variabila c va retine numai ³ora´). //a fost pus terminatorul de sir. In acest caz. cout<<c. Dezavantajul este ca in acest fel nu se pot citi siruri care contin mai multe cuvinte separate prin spatii. deci sirul va fi afisat corect //se va afisa sirul format din cele 6 caractere.h (varianta recomandata). Äreziduale´. Exemplu char c[30]. urmat de caractere Se poate face pur si simplu. Citirea unui sir de caractere se poate face ca citirea oricarui tablou. intr-un for. Se poate folosi o functie speciala pentru citirea sirurilor de caractere. din cauza ca n-a fost pus terminatorul de sir c[6]=0. folosind cin>>.i<=5. Exemplu: char c[20]. //initializate implicit la compilare. for(int i=0. cout<<c<<endl. Caracterul nul este adaugat automat. el trebuie pus explicit dupa ultimul caracter din sir. Citirea sirului se sfarseste la intalnirea primului caracter blank (de ex. cout<<c<<endl. inclusa in biblioteca string.i++) cin>>c[i].

int nr. dupa fiecare folosire trebuie citit caracterul de la sfarsitul fiecarui sir .get(a.¶t¶). variabila a va retine ³maimu´ //daca se citeste sirul ³maimuta.x. sau daca s-a intalnit caracterul x.get(b. Functia cin.15. cin.nr.15. cin. a carui citire se termina la caracterul Enter.get(a.get(a. acest caracter va fi incarcat la inceputul urmatorului sir. caz in care el este implicit caracterul ¶\n¶ (new line). cin. adica ¶\n¶ (in caz contrar. Exemplu char a[30]. cin. deci citirea celui de-al doilea sir se termina inainte de a incepe. iar al doilea sir va fi sirul vid).4. variabila a va retine ³mai´ //daca se citeste sirul ³maimuta. Exemplu char a[30].get(a.¶t¶). Aceasta citire a caracterului ¶\n¶ se realizeaza folosind cin. cin. caracterul nul este inserat automat iar caracterul transmis ca ultim parametru nu este inserat in sir.10).¶s¶). variabila a va retine ³maimuta´ Functia cin. variabila a va retine ³maim´ //daca se citeste sirul ³maimuta.10). cin.get() fara parametri.15).get(a. 9 .get(a.x).get(a.5. cin.get( ) fara parametri are rolul de a citi un caracter (alb sau nu). Al treilea parametru poate lipsi.char a[30]. //daca se citeste sirul ³maimuta.nr. variabila a va retine ³maimuta´ //daca se citeste sirul ³maimuta.b[30]. Sunt citite si caracterele albe.get(char c) are rolul de a citi un caracter (alb sau nu) pe care il incarca in variabila c. Functia cin.¶s¶). Observatie: In cazul utilizarii repetate a functiei cin.get citeste un sir de caractere sau pana cand au fost citite nr-1 caractere. cin.x).get(a.

b[40]=´al doilea sir´. ca in cazul tablourilor. b=´´ (nici nu apucam sa citim sirul b). 10 . Exemplu: char a[50]=´primul sir´. dar aceasta varianta nu este recomandata.sir_sursa). Se poate afisa si caracter cu caracter. Varianta corecta este: cin. ± returneaza lungimea efectiva a unui sir (fara a numara terminatorul de sir).15). ATENTIE!! Nu este permisa atribuirea intre doua siruri de caractere folosind operatorul =.get(a.Daca se incearca citirea sirurilor Äsarbatoare´ si Ävacanta´.10).get(b. ± copiaza sirul sir_ sursa in sir_destinatie (se simuleaza atribuirea a=b). cin. Exemplu: char a[50]=´ora de informatica´. Afisarea unui sir de caractere se face folosind cout. Atribuirea se face folosind functia strcpy. à strlen(a) = 18 Ø Functia strcpy strcpy(sir_destinatie.get(). cin.h>. cout<<a. Ø Functia strlen int strlen(nume_sir). se observa ca a=´sarbatoare´. FUNCTII PENTRU OPERATII CU SIRURI DE CARACTERE Functiile pentru operatii cu siruri se gasesc in header-ul <string.

b. à se tipareste ´ta este un sir´.nr). iar functia intoarce adresa subsirului care incepe cu prima aparitie a caracterului c. 11 . ± are rolul de a cauta caracterul c in sirul sir. cout<<strchr(a.c). Sirul sursa ramane nemodificat.b=¶t¶. Exemplu: char *a=´acesta este un sir´. Daca nu este gasit caracterul. ± adauga dest primele nr caractere din sirul sursa. Exemplu: char *a=´vine ´.sursa). à nu se tipareste nimic (se tipareste 0 daca se face o conversie la int a lui strchr(a.b). ± adauga sirului dest sirul sursa. Diferenta dintre adresa sirului initial si cea a subsirului returnat reprezinta chiar pozitia caracterului cautat in sirul dat. à a = ´vine vacanta?´. b=´al doilea sir´. functia returneaza 0.c). cout<<strchr(a.b). à a = ´vine vaca´.sursa.c) . Operatia se numeste concatenare si nu este comutativa. strcat(a. Sirul sursa ramane nemodificat. strncat(a.*b=´vacanta?´. Ø Functia strcat strcat(dest.a=b. Exemplu: char *a=´vine ´. à a = ´al doilea sir´.4). Ø Functia strncat strncat(dest. Cautarea se face de la stanga la dreapta.c=¶x¶.b). //eroare strcpy(a. Ø Functia strchr strchr(sir.d.*b=´vacanta?´.

p=strchr(p.d= strchr(a. p++.c. cu deosebirea ca returneaza adresa ultimei aparitii a caracterului (cautarea se face de la dreapta spre stanga.get(a.h> void main() {char a[100]. =0 (daca sir1=sir2) si >0 (daca sir1>sir2). Functia strcmp face distinctie intre literele mari si cele mici ale alfabetului.100). r = right) Ø Functia strcmp int strcmp(sir1. Obs: Functia strcmp returneaza diferenta dintre codurile ASCII ale primelor caractere care nu coincid 12 .sir2).c).c). p=strchr(a.*p. Valoarea returnata este <0 (daca sir1<sir2). ± are rolul de a compara doua siruri de caractere.c). cout<<´Caracterul apare prima data la pozitia ´<<d-a.}} Ø Functia strrchr strrchr(sir.b). Ex: Sa se afiseze toate pozitiile unui caracter intr-un sir #include <iostream. cin>>c.h> #include <string. cin. while (p) {cout<<"Pozitia "<<p-a<<endl. ± are acelasi rol cu strchr.

Functia intoarce adresa primului caracter al primei entitati. o Cand sirul nu mai contine entitati.h> 13 . adaugand automat dupa ea caracterul nul.sir2). ± are rolul de a separa sirul sir1 in mai multe siruri (cuvinte) separate intre ele prin unul sau mai multe caractere cu rol de separator. Cautarea se face de la stanga la dreapta Ø Functia strtok strtok(sir1. Exemplu: //Sa se separe cuvintele dintr-un text. cu deosebirea ca nu face distinctie intre literele mari si cele mici ale alfabetului (i = ignore).sir2). ± are rolul de a identifica daca sirul sir2 este subsir al sirului sir1. Daca este. o Urmatoarele apeluri sunt de forma strtok(NULL.Ø Functia stricmp int stricmp(sir1. functia returneaza adresa nula. In cazul in care sir2 apare de mai multe ori in sir1. ± are acelasi rol cu strcmp. Functia strtok actioneaza in felul urmator: o Primul apel trebuie sa fie de forma strtok(sir1. se returneaza adresa de inceput a primei aparitii.sir2).sir2). separatorul este inlocuit automat prin caracterul nul.sir2).h> #include <conio. altfel returneaza adresa 0. #include <iostream. Dupa prima entitate.h> #include <string. De fiecare data. functia intoarce adresa de inceput a urmatoarei entitati. functia returneaza adresa de inceput a subsirului sir2 in sirul sir1. Ø Functia strstr strstr(sir1. Sirul sir2 este alcatuit din unul sau mai multe caractere cu rol de separator.

clrscr().cuv[10][10].100). cout<<"Dati sirul:". 14 . Ø Functia strcspn cu forma generala int strspn(sir1. p=strtok(p..*r. !?". à returneaza 0.separator).´16A32BF´). à returneaza 2. p=strtok(NULL.nr=0.cin.i++) cout<<cuv[i]<<endl. getch(). Exemplu: strspn(³AB2def´. strcpy(p. pentru ca primele 2 caractere µA¶ si µB¶ din sir1 se gasesc in sir2. for (i=1. while (p) {strcpy(cuv[++nr].} Ø Functia strspn cu forma generala int strspn(sir1.int i=0.get(text.*p.separator). ± are rolul de a returna numarul de caractere ale sirului sir1 (caractere consecutive care incep obligatoriu cu primul caracter) care se gasesc in sirul sir2.} cout<<"Sunt "<<nr<<" cuvinte:"<<endl. strspn(³FAB2def´.separator[]=".text).sir2).void main() {char text[100].´1B3AQW´). ± are rolul de a returna numarul de caractere ale sirului sir1 (caractere consecutive care incep obligatoriu cu primul caracter) care nu se gasesc in sirul sir2.i<=nr.p).sir2). deoarece caracterul µF¶ cu care incepe sir1 nu se gaseste in sir2.

get(text. clrscr().cifre[]="0123456789". pentru ca primele 2 caractere din sir1 nu se gasesc in sir2. #include <iostream. Restul caracterelor raman neschimbate. ± are rolul de a converti toate literele mici din sir in litere mari.´123´).h> #include <string. getch().cin.Exemplu: strspn(³AB2def´. else cout<<´nenumeric´. Ø Functia strupr cu forma generala strupr(sir). Sa se decida daca sirul este alcatuit exclusiv din caractere numerice. Restul caracterelor raman neschimbate Ø Functia strbrk cu forma generala 15 .h> void main() {char text[100].} Ø Functia strlwr cu forma generala strlwr(sir).100).h> #include <conio. //Se citeste un sir de caractere care nu contine caractere albe. cout<<"Dati sirul:". if (strcspn(cifre. ± are rolul de a converti toate literele mari din sir in litere mici. à returneaza 2.text)==strlen(text)) cout<<"exclusiv numeric".

sir. ± converteste o valoare de tip int in sir. returneaza adresa sa din cadrul sirului sir1 si executia se termina. Baza retine baza de numeratie catre care sa se faca conversia. returneaza adresa sa din cadrul sirului sir1 si executia se termina. Altfel. Aceasta functie (ca si cele similare) necesita includerea librariei stdlib. o o nula. ± actioneaza in felul urmator: o Cauta primul caracter al sirului sir1 in sir2. care este memorat in variabila sir. 16 . Ø Functia atoi cu forma generala int atoi(sir). sirul retine si eventualul semn -. Ø Functia _atold cu forma generala long double _atold(sir).strpbrk(sir1. Daca aceasta conversie esueaza (se intalneste un caracter nenumeric). Ø Functia atol cu forma generala long atol(sir). Daca este gasit. se trece la pasul urmator. valoarea intoarsa este 0. Daca este gasit. o Cauta al doilea caracter al sirului sir1 in sir2. Ø Functia itoa cu forma generala itoa(int valoare. « Daca nici un caracter al sirului sir1 nu apartine sirului sir2. se trece la pasul urmator. Daca aceasta conversie esueaza. ± converteste un sir catre tipul long double.h. ± converteste un sir catre tipul long.int baza). functia returneaza adresa Ø Functia atof cu forma generala double atof(sir). valoarea intoarsa este 0. Daca aceasta conversie esueaza (se intalneste un caracter nenumeric). In cazul bazei 10. Altfel. Daca aceasta conversie esueaza (se intalneste un caracter nenumeric). valoarea intoarsa este 0.sir2). ± converteste un sir catre tipul double. valoarea intoarsa este 0. ± converteste un sir catre tipul int.

± converteste o valoare de tip long int in sir. care este memorat in variabila sir. Ø Functia ultoa cu forma generala ultoa(unsigned long valoare.int baza).int baza).sir. ± converteste o valoare de tip unsigned long in sir.sir. care este memorat in variabila sir.Ø Functia ltoa cu forma generala ltoa(long valoare. 17 .

Sign up to vote on this title
UsefulNot useful