Sunteți pe pagina 1din 10

Lucrarea 1.

Liste
--------------------------------------------------------------------------------------------------------------------------------

LISTE

1.1. VARIABILE DINAMICE


Pentru variabilele statice dimensiunea zonei de memorie necesar este stabilit
naintea executrii programului prin declararea variabilei respective. Variabilele dinamice
sunt acele variabile a cror dimensiune nu este cunoscut nainte de executarea
programului. Astfel, memoria necesar acestor variabile este alocat prin instruciuni n
cadrul programului, iar cnd aceste variabile nu mai sunt necesare, memoria este eliberat
tot prin instruciuni care fac parte din program.
Spaiul de memorie alocat la cerere este accesibil prin pointeri (variabile statice de
tip adres de variabil) i este localizat ntr-o zon de memorie numit heap, diferit de
zona de memorie program i de cea alocat stivei. n C, numele de variabile nu se pot
genera dinamic. Ca urmare, o variabil dinamic din heap trebuie s fie referit indirect
printr-un pointer aflat ntr-o variabil alocat static sau pe stiv. Variabila alocat pe heap
este o variabil alocat dinamic, deoarece adresa ei este asociat indirect unui nume.
Prototipurile funciilor folosite pentru alocarea i eliberarea memoriei n timpul
execuiei programului se gsesc n biblioteca de funcii C, n fiierele alloc.h i stdlib.h
stdlib.h.
Funciile cele mai des folosite sunt malloc() i free()
free().
Funcia malloc() are declaraia:
void *malloc(size_t size);
i aloc un bloc de memorie de size octei. Valoarea returnat este un pointer void spre
blocul de memorie nou alocat. n caz de eroare (dac nu exist spaiu suficient de
memorie pentru noul bloc), malloc() returneaz NULL NULL. Dac argumentul size este 0,
malloc() returneaz NULLNULL. Spaiul alocat permite memorarea oricrui tip de date, iar
pentru a obine un pointer la un alt tip de dat dect void, se utilizeaz operatorul cast
(pentru conversie de tip). De asemenea, se va utiliza operatorul sizeof pentru specificarea
dimensiunii zonei solicitate. Alte funcii disponibile pentrum alocarea memoriei sunt
calloc(), farcalloc(), farmalloc(), realloc().
Funcia free() are declaraia:
void free(void *block);
i elibereaz un bloc de memorie alocat anterior prin apelul uneia din funciile malloc(),
calloc(), sau realloc()
realloc(). Numrul de octei eliberai este cel specificat n momentul n care
blocul a fost alocat sau realocat. Dup apel, blocul de octei eliberat este disponibil pentru
alocare. Funcia nu ntoarce nici o valoare.

1
Lucrarea 1. Liste
--------------------------------------------------------------------------------------------------------------------------------

1.2. REPREZENTAREA LISTELOR

Lista este o structur de date omogen, secvenial, format din elementele listei,
numite i noduri ale listei, care nu trebuie s fie neaprat adiacente n memorie.
n cazul listelor simplu nlnuite un element din list conine unul sau mai multe
tipuri de informaie propriu-zis i o informaie de legtur, care este un pointer ctre
nodul succesor.
Tipul unui element al unei liste simplu nlnuite va fi declarat astfel:
struct TipNod
{
TipInfo1 Info1;
TipInfo2 Info2;
...
TipInfoN InfoN;
TipCheie Cheie;
struct TipNod* Legatura;
};
struct TipNod Nod;

Structura de date este recursiv deoarece cmpul informaiei de legtur este de


tip pointer la tipul nodului. Cmpul cheie este opional i se poate folosi atunci cnd se
dorete realizarea unei operaii asupra listei n funcie de acesta. De asemenea, orice cmp
de informaie poate deveni cmp cheie.

Structura de date are o reprezentare ca n figura 1.1.

Info1 Info2 InfoN Cheie Legatura

Fig.1.1. Structura de date asociat nodului unei liste

Listele simplu nlnuite sunt structuri obinute prin concatenarea de noduri de


tipul descris mai sus prin intermediul cmpului de legtur. Lista va fi un pointer ctre o
structur ce va avea dou elemente Prim i Ultim, numite santinele, ntre care se vor
insera nodurile propriu-zise ale listei, care conin informaie. De asemenea. lista va mai
avea un nod Curent, care va indica poziia n list a nodului asupra cruia se pot face
prelucrri. Lista va mai conine n structura sa i un cmp care s-i indice lungimea.
struct TipLista
{
int Lungime;

2
Lucrarea 1. Liste
--------------------------------------------------------------------------------------------------------------------------------

struct TipNod *Prim, *Curent, *Ultim;


};
struct TipLista *ListaPtr;

O list simplu nlnuit poate fi parcurs doar de la nodul Prim la nodul Ultim i
va arta astfel;
Info Legatura Info Legatura Info Legatura NULL

Prim Ultim

Fig.1.2. Structura unei liste simplu nlnuite

1.3. OPERAII CU LISTE


Operaiile care se pot efectua asupra unei liste simplu nlnuite sunt urmtoarele:
crearea listei, adic iniializarea listei i crearea nodurilor santinel;
operaii de testare:
testare listvid;
testare lungime list;
testare a elementului curent dac este primul/ultimul element;

operaii de poziionare a pointerului curent:


poziionare pe primul element urmtor santinelei Prim;
poziionare pe ultimul element anterior santinelei Ultim;
poziionare pe elementul precedent;
poziionare pe elementul urmtor;
poziionare pe un element indicat de un cmp cheie;

operaii de modificare a listei:


adugare element la sfritul listei (Fig.1.3);
inserare element la dreapta elementului curent (Fig.1.3);
inserare element la stnga elementului curent (Fig.1.3);
tergere element (Fig.1.4);
modificare informaii din nodul curent;
permutare informaii cu nodul din stnga/dreapta;
ordonare a elementelor listei dup un cmp cheie;

operaii care permit citirea informaiilor coninute n list:


afiarea ntregii liste;

3
Lucrarea 1. Liste
--------------------------------------------------------------------------------------------------------------------------------

afiarea unui element;

operaii efectuate cu mai multe liste:


concatenare;
interclasare (pentru liste ordonate);
copierea unei liste ntr-o alt list;
separarea n mai multe liste dup un criteriu.

Info Legatura Info Legatura Info Legatura

Info Legatura

Fig.1.3. Inserarea unui element ntr-o list

Info Legatura Info Legatura Info Legatura Info Legatura

Fig.1.4. tergerea unu


unuii element dintr-o list

1.4. DESFURAREA LUCRRII

Se va realiza un program care s implementeze o agend telefonic cu ajutorul


unei liste simplu nlnuite.
Programul va trebui srealizeze:
crearea unei liste vide;
adugarea unor elemente noi la list;
afiarea ntregii liste;

ordonarea elentelor listei dup un anumit criteriu (dup cmpul Ord).


#include <alloc.h>
#include <conio.h>
#include <stdio.h>

4
Lucrarea 1. Liste
--------------------------------------------------------------------------------------------------------------------------------

typedef struct Info


{
char Nume[20];
char Tel[12];
int Ord;
};

struct Nod
{
struct Info Date;
struct Nod* Urm;
};

struct Lista
{
int Lungime;
struct Nod *Prim, *Curent, *Ultim;
};
int Creare (struct Lista *ListaPtr);
int TestVida (struct Lista *ListaPtr);
int Primul (struct Lista *ListaPtr);
int Ultimul (struct Lista *ListaPtr);
int Lungime (struct Lista *ListaPtr);
int Inceput (struct Lista *ListaPtr);
int Sfarsit (struct Lista *ListaPtr);
int Precedent (struct Lista *ListaPtr);
int Pozitionare (struct Lista *ListaPtr, int Pozitie);
void AdaugaSfarsit (struct Lista *ListaPtr, struct Info Nou);
void AdaugaDreapta (struct Lista *ListaPtr, struct Info Nou);
int Stergere (struct Lista *ListaPtr);
int PermDreapta (struct Lista *ListaPtr);
void Ordonare (struct Lista *ListaPtr);
void Afisare (struct Lista *ListaPtr);
void AfisareMeniu ();
void InDatePers (struct Lista *ListaPtr, struct Info InfoInreg);

char c;
struct Lista *ListaTel;
struct Info InfoPers;
int Poz;
int Creare (struct Lista *ListaPtr)
{
ListaPtr->Prim=(struct Nod *)malloc(sizeof(struct Nod));
if (!ListaPtr->Prim) return 0;
ListaPtr->Ultim=(struct Nod *)malloc(sizeof(struct Nod));
if (!ListaPtr->Ultim) return 0;
ListaPtr->Prim->Urm=ListaPtr->Ultim;
ListaPtr->Ultim->Urm=NULL;
ListaPtr->Lungime=0;
ListaPtr->Curent=ListaPtr->Prim;
return 1;
}
int TestVida (struct Lista *ListaPtr)
{
return ListaPtr->Lungime==0;

5
Lucrarea 1. Liste
--------------------------------------------------------------------------------------------------------------------------------

int Primul (struct Lista *ListaPtr)


{
return (ListaPtr->Prim->Urm==ListaPtr->Curent)&&(!TestVida(ListaPtr));
}

int Ultimul (struct Lista *ListaPtr)


{
return (ListaPtr->Curent->Urm==ListaPtr->Ultim)&&(!TestVida(ListaPtr));
}

int Lungime (struct Lista *ListaPtr)


{
return ListaPtr->Lungime;
}

int Inceput (struct Lista *ListaPtr)


{
if (TestVida(ListaPtr)) return 0;
else
{
ListaPtr->Curent=ListaPtr->Prim->Urm;
return 1;
}
}

int Sfarsit (struct Lista *ListaPtr)


{
if (TestVida(ListaPtr)) return 0;
else
{
ListaPtr->Curent=ListaPtr->Ultim;
if (Precedent(ListaPtr)) return 1;
else return 0;
}
}

int Urmator (struct Lista *ListaPtr)


{
if (TestVida(ListaPtr)) return 0;
else
{
if (ListaPtr->Curent->Urm!=ListaPtr->Ultim)
{
ListaPtr->Curent=ListaPtr->Curent->Urm;
return 1;
}
else return 0;
}
}

int Precedent (struct Lista *ListaPtr)


{
struct Nod *Temp;

6
Lucrarea 1. Liste
--------------------------------------------------------------------------------------------------------------------------------

if (ListaPtr->Lungime==0) return 0;
if (ListaPtr->Lungime==1)
{
ListaPtr->Curent=ListaPtr->Prim->Urm;
return 0;
}
Temp=ListaPtr->Curent;
ListaPtr->Curent=ListaPtr->Prim;
if (Temp==ListaPtr->Prim) return 0;
else
{
while (ListaPtr->Curent->Urm!=Temp && Urmator(ListaPtr));
return 1;
}
}

int Pozitionare (struct Lista *ListaPtr, int Pozitie)


{
int l;
l=Lungime(ListaTel);

if (Inceput(ListaPtr))
{
do
{
if(ListaPtr->Curent->Date.Ord==Pozitie) return(1);
Urmator(ListaPtr);
l--;
}
while (l>0);
return 0;
}
else return 0;
}

void AdaugaSfarsit (struct Lista *ListaPtr, struct Info Nou)


{
struct Nod *Elem;
Sfarsit (ListaPtr);
Elem=(struct Nod *)malloc(sizeof(struct Nod));
Elem->Urm=ListaPtr->Ultim;
Elem->Date=Nou;
ListaPtr->Curent->Urm=Elem;
ListaPtr->Curent=Elem;
ListaPtr->Lungime++;
}

void AdaugaDreapta (struct Lista *ListaPtr, struct Info Nou)


{
struct Nod *Elem;
Elem=(struct Nod *)malloc(sizeof(struct Nod));
Elem->Urm=ListaPtr->Curent->Urm;
Elem->Date=Nou;
ListaPtr->Curent->Urm=Elem;
ListaPtr->Lungime++;
}

7
Lucrarea 1. Liste
--------------------------------------------------------------------------------------------------------------------------------

int Stergere (struct Lista *ListaPtr)


{
struct Nod *Elem;
if (Lungime(ListaPtr))
{
Precedent(ListaPtr);
Elem=ListaPtr->Curent->Urm;
ListaPtr->Curent->Urm=Elem->Urm;
free(Elem);
ListaPtr->Lungime--;
return 1;
}
else return 0;
}

int PermDreapta (struct Lista *ListaPtr)


{
if (ListaPtr->Lungime>1)
{
struct Nod *Temp1=ListaPtr->Curent, *Temp2=ListaPtr->Curent->Urm;
ListaPtr->Curent->Urm=ListaPtr->Curent->Urm->Urm;
if (Precedent(ListaPtr)) {}
ListaPtr->Curent->Urm=Temp2;
Temp2->Urm=Temp1;
ListaPtr->Curent=Temp1;
return 1;
}
else return 0;
}

void Ordonare (struct Lista *ListaPtr)


{
int i,j;
if (Inceput(ListaPtr))
for (i=1;i<Lungime(ListaPtr);i++)
{
if (Inceput(ListaPtr))
for (j=i;j<Lungime(ListaPtr);j++)
{
if (ListaPtr->Curent->Date.Ord>ListaPtr->Curent->Urm->Date.Ord)
PermDreapta(ListaPtr);
else Urmator(ListaPtr);
}
}
}

void Afisare(struct Lista *ListaPtr)


{
clrscr();
printf ("Lista contine elementele:\n");
if (Inceput(ListaPtr))
{
do {
printf("%d ",ListaPtr->Curent->Date.Ord);
printf("Nume: %s, Telefon: %s\n",ListaPtr->Curent->Date.Nume,

8
Lucrarea 1. Liste
--------------------------------------------------------------------------------------------------------------------------------

ListaPtr->Curent->Date.Tel);
}
while (Urmator(ListaPtr));
printf("Lista are %d abonati.", Lungime(ListaPtr));
}
else printf("Lista este vida\n");
}

void AfisareMeniu(void)
{
clrscr();
gotoxy(20,10);
printf("1.Creare lista - C");
gotoxy(20,11);
printf("2.Adaugare la lista - A");
gotoxy(20,12);
printf("3.Stergere din lista - S");
gotoxy(20,13);
printf("4.Ordonare lista - O");
gotoxy(20,14);
printf("5.Printare lista - P");
gotoxy(20,15);
printf("6.Final program -F");
}

void InDatePers (struct Lista *ListaPtr, struct Info InfoInreg)


{
clrscr();
printf("Introduceti numele persoanei\n");
fflush(NULL);
gets (InfoInreg.Nume);
printf("Introduceti telefonul persoanei\n");
fflush(NULL);
gets(InfoInreg.Tel);
printf("Introduceti numarul de ordine\n");
fflush(NULL);
scanf ("%d", &InfoInreg.Ord);
AdaugaSfarsit (ListaPtr, InfoInreg);
}

void main(void)
{
do
{
AfisareMeniu();
c=getch();
switch(c)
{
case '1':
case 'c':
case 'C':
Creare(ListaTel);
clrscr();
printf("Lista a fost creata!");
getch();
break;

9
Lucrarea 1. Liste
--------------------------------------------------------------------------------------------------------------------------------

case '2':
case 'a':
case 'A':
InDatePers(ListaTel, InfoPers);
break;
case '3':
case 's':
case 'S':
clrscr();
printf("Numarul de ordine : ");
scanf("%d",&Poz);
if(Pozitionare (ListaTel,Poz))
{
Stergere (ListaTel);
} else
{
printf("Elementul nu exista!");
getch();
break;
}
clrscr();
printf("Elementul a fost sters!");
getch();
break;
case '4':
case 'o':
case 'O':
Ordonare(ListaTel);
clrscr();
printf("Lista a fost ordonata!");
getch();
break;
case '5':
case 'p':
case 'P':
Afisare(ListaTel);
getch();
break;
case '6':
case 'f':
case 'F':
clrscr();
printf("Program terminat!");
break;
default:
clrscr();
printf("Optiune grsita!\n");
getch();
break;
}
}
while ((c!='4') && (c!='f') && (c!='F'));
}

10

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