You are on page 1of 7

Capitolul 11 Liste simplu nlnuite

Obiectiv: familiarizarea cu noiunile de alocare dinamic i folosirea listelor. Activiti: - Prezentarea listelor simplu nlnuite; - Prezentarea operaiilor de baz cu liste simplu nlnuite (adugare, cutare, tergere);

11.1 Noiuni introductive


O list simplu nlnuit este o structur de date ce utilizeaz alocarea dinamic a memoriei. Un element al listei se numete nod. Fiecare nod al unei liste conine un cmp care are rolul de a indica adresa urmtorului element din list. Exemplu:
typedef struct student { char nume[20]; float grupa; struct student *urm; }nod; 1000 Ionel 1.2 7000

/*campul de inlantuire*/ 7000 Mircea 2.1 2000 2000 Ana 1.1 NULL

Figura 11.1 Exemplu de list simplu nlanuit

11.2 Crearea listelor simplu nlnuite


O lista simplu nlnuit poate fi creata n felul urmtor: Prin inserare la nceput; Prin inserare la sfrit; Prin inserare ordonat;

Toate operaiile de inserare a unui nod ntr-o list presupun nti alocarea dinamic a memoriei pentru nodul ce urmeaz s se insereze. n cazul n care avem cmpuri de tip ir de caractere declarate ca i pointer la char, trebuie alocat memorie i pentru ele. Pentru alocare se utilizeaz funcia malloc.
nod *p=(nod*)malloc(sizeof(nod));

Dup alocare urmeaz introducerea informaiei utile n cmpurile nodului. Pentru exemplul considerat:
strcpy(p->nume,Ionel); p->grupa=1.2; p->urm=NULL;

Toate operaiile cu liste simplu nlnuite (inserare, cutare, tergere,afiare) pornesc de la primul element al listei. Accesul la un anumit element al listei se face secvenial, accesnd

Programarea Calculatoarelor

Capitolul 11 Liste simplu nlanuite

nodurile aflate naintea sa n nlanuire i pornind de la primul element al listei. Dac lista este vid primul element indic spre NULL. n exemplele urmtoare vom considera c p este nodul care se insereaz, q este pointerul folosit pentru a parcurge lista, prim este primul nod al listei. 11.2.1 Inserarea la nceput Nodul se insereaz naintea primului element, deci nodul care l urmeaz este primul element, n urma inserrii el devine noul prim.
p->urm=prim; prim=p; prim p prim urm urm urm NULL
Figura 11.2 Inserarea la nceput

11.2.2 Inserarea la sfrit nti se verific dac lista este vid sau nu. Dac lista este vid primul nod devine cel alocat. Altfel se parcurge lista pn cnd se ajunge la ultimul nod. Pentru a putea realiza cu uurin legtura dintre ultimul nod i cel care urmeaz s se insereze lista va fi parcurs cu q>urm. Urmtorul ultimului nod devine nodul alocat.
p->urm=NULL; if(prim==NULL ) prim=p; else { q=prim; while(q->urm!=NULL) q=q->urm; q->urm=p; } prim urm urm q urm p

Figura 11.3 Inserarea la sfrit

NULL

11.2.3 Inserarea ordonat a unui nod ntr-o list n situaia n care se dorete afiarea ordonat a nodurilor listei n funcie de informaia dintr-un cmp, se poate crea o list ordonat dup informaia din cmpul respectiv. Cmpul dup care se ordoneaz elementele din lista se numete cmp cheie. Inserarea ordonat a unui nod ntr-o list presupune parcurgerea listei cu scopul gsirii poziiei n care trebuie inserat nodul, astfel nct lista s rmn ordonat dupa inserarea lui. La inserarea ordonat a unui nod ntr-o list se disting urmtoarele situaii: lista este vid i nodul inserat devine primul din list;

Programarea Calculatoarelor

Capitolul 11 Liste simplu nlanuite

nodul se insereaz la nceputul listei (devine noul prim); nodul se insereaz pe parcurs sau la sfrit n list; Exemplu:
if(prim==NULL) return p; /*inserarea primului nod*/ else if(strcmp(prim->nume,p->nume)>0) { p->urm=prim;/* inserare inainte de primul nod*/ return p; } else { q=prim;
while(q->urm!=NULL && strcmp(q->urm->nume,p->nume)<0)

q=q->urm; p->urm=q->urm;/*inserare pe parcurs sau la sfarsit*/ q->urm=p; return prim; } prim Alina 4.2 urm q Mircea 1.2 urm Victor 3.2 NULL Paul 1.2 urm
Figura 11.4 Inserarea ordonat

11.3 tergerea unui nod din list


La teregea unui nod din list se disting urmtoarele situaii: se terge primul nod (noul prim devine cel care-l urmeaz); se terge un nod din interiorul listei sau de la sfrit; tergerea unui nod presupune refacerea legturilor i eliberarea memoriei ocupate de nodul respectiv. Dac se terege primul nod, noul prim devine cel care l urmeaz. Dac se sterge un nod din interiorul listei, trebuie facut legtura dintre nodul dinaintea lui i nodul care l urmeaz.
nod* stergere(nod *prim,char *nume){ nod *q,*p; if(prim!=NULL) /*daca lista nu este vida*/ { if(strcmp(prim->nume,nume)==0) { q=prim; prim=prim->urm; /*stergerea primului nod*/ free(q); return prim; }

Programarea Calculatoarelor

Capitolul 11 Liste simplu nlanuite

q=prim; while(q->urm!=NULL && strcmp(q->urm->nume,nume)!=0) q=q->urm; if(q->urm!=NULL && strcmp(q->urm->nume,nume)==0) { p=q->urm; q->urm=q->urm->urm;/*stergerea unui nod din interiorul listei sau de la sfarsit*/ free(p); } return prim; } else { printf(\nLista vida!); return prim; } } prim urm q urm urm urm NULL

Figura 11.5 tergerea unui nod din list

11.4 Parcurgerea listei


Parcurgerea unei liste simplu nlnuit se realizeaz plecnd de la primul element:
q=prim; while(q!=NULL) { printf("\n%s %1.f",q->nume,q->grupa); q=q->urm; }

11.5 Program rezolvat:


S se scrie un program pentru evidena studenilor unui an de studiu. Pentru rezolvarea problemei se vor folosi liste simplu nlnuite. Informaiile de interes sunt numele studentului i grupa. Programul va implementa urmtoarele operaii: 1. Introducerea unui student; 2. Afisarea ordonat a studenilor; 3. Cutare unui student; 4. tergerea unui student;
#include<stdio.h> #include<stdlib.h> #include<conio.h> #include<string.h> typedef struct student { char *nume; float grupa; struct student *urm; }nod;

Programarea Calculatoarelor

Capitolul 11 Liste simplu nlanuite

nod *adauga(nod*prim,char *nume,float grupa) { nod *q,*p; p=(nod*)malloc(sizeof(nod)); p->nume=(char*)malloc(strlen(nume)+1); strcpy(p->nume,nume); p->grupa=grupa; p->urm=NULL; if(p==NULL || p->nume==NULL) { printf("Eroare la alocare!"); exit(0); } if(prim==NULL) return p; else if(strcmp(prim->nume,p->nume)>0) { p->urm=prim; return p; } else { q=prim;
while(q->urm!=NULL && strcmp(q->urm->nume,p->nume)<0)

q=q->urm; p->urm=q->urm; q->urm=p; return prim; } } void afisare(nod *prim){ nod *q; q=prim; while(q!=NULL){ printf("\n%s %.1f",q->nume,q->grupa); q=q->urm; } } nod* cautare(nod *prim,char *nume){ nod *q; q=prim; while(q!=NULL && strcmp(q->nume,nume)!=0) q=q->urm; return q; } nod* stergere(nod *prim,char *nume){ nod *q,*p;

Programarea Calculatoarelor

Capitolul 11 Liste simplu nlanuite

if(prim!=NULL) { if(strcmp(prim->nume,nume)==0) { q=prim; prim=prim->urm; free(q->nume); free(q); return prim; } q=prim; while(q->urm!=NULL && strcmp(q->urm->nume,nume)!=0) q=q->urm; if(q->urm!=NULL && strcmp(q->urm->nume,nume)==0) { p=q->urm; q->urm=q->urm->urm; free(p->nume); free(p); } return prim; } else return prim; } int main(){ int opt; nod *prim,*p; char nume[10]; float grupa; prim=NULL; while(1){ clrscr(); printf("\n1. Introducerea unui student"); printf("\n2. Afisarea alfabetica a studentilor introdusi"); printf("\n3. Cautarea unui student"); printf("\n4. Stergerea unui student"); printf("\n5. Iesire\n"); scanf("%d",&opt); fflush(stdin); switch(opt) { case 1:printf("Numele:"); gets(nume); printf("Grupa:"); scanf("%f",&grupa); prim=adauga(prim,nume,grupa); break; case 2:afisare(prim); break; case 3:printf("Introduceti numele studentului

Programarea Calculatoarelor

Capitolul 11 Liste simplu nlanuite

cautat:"); gets(nume); p=cautare(prim,nume); if(p==NULL) printf("Studentul nu se gaseste in lista!"); else printf("%s %.1f",p->nume,p->grupa); break; case 4:printf("Introduceti numele studentului:"); gets(nume); prim=stergere(prim,nume); afisare(prim); break; case 5:exit(1); default:printf("\n1..5!"); } getch(); } return 0; }

11.6 Probleme propuse


1. ntr-un depozit se afl diverse utilaje. Informaiile de interes pentru fiecare utilaj sunt: denumirea, anul de fabricaie, sectorul de depozitare. S se scrie un program care realizeaz urmtoarele: a) Introducerea unui utilaj; b) Afiarea utilajelor din depozit, c) Mutarea unui utilaj dintr-un sector n altul; d) Afisarea n ordine descresctoare a vechimii, a utilajelor dintr-un sector citit de la tastatur; e) tergerea unui utilaj; Pentru rezolvarea problemei se vor utiliza liste simplu inlanuite. Se consider o list simplu nlnuit. S se inverseze nodurile listei. (primul devine ultimul, etc). Se propune realizarea unui program C care s implementeze o stiv utiliznd alocarea dinamic. Elementele stivei sunt reprezentate de adrese (nume strad i numr). Se vor implementa operatorii: a) push pune un element n vrful stivei; b) pop extrage elementul aflat n vrful stivei; c) display - afiseaz coninutul stivei;

2. 3.

11.7 Intrebri recapitulative


1. 2. 3. 4. Precizai care sunt avantajele i dezavantajele oferite de alocarea dinamic a memoriei n comparaie cu alocarea static a memoriei. Precizai care sunt funciile care permit alocarea respectiv eliberarea dinamic a memoriei. Care sunt modalitile de inserare a unui nod ntr-o list? Precizai modul de realizare a legturilor n toate variantele. Precizai modul de refacere al legturilor la tergerea unui nod.

You might also like