Sunteți pe pagina 1din 17

Ministerul Educaţiei al Republicii Moldova

Universitatea Tehnică a Moldovei

Catedra Informatică Aplicată

RAPORT
Lucrarea de laborator nr.2-3
la disciplina Structuri de date si Algoritmi

A efectuat:
st. gr. C-171 F.Minzat

A verificat:
dr., conf.univ., catedra IA M. Kulev

Chişinău – 2018
Lucrare de laborator 2-3

Tema: Implementarea tipului de date abstract “Lista simplu inlantuita” in C

Scopul lucrarii: obtinerea deprinderilor practice de implementare a unui tip de


date abstract (TDA) in limbajul C si anume a TDA “Lista simplu inlantuita”

Sarcina de lucru: De scris trei fisiere in limbajul C pentru implementarea (2


fisiere) si utilizarea (1 fisier – program cu functia main ) a TDA “Lista simplu
inlantuita”:

1. Fișierul antet cu extensia .h care descrie structura de date a elementului


listei simplu inlantuite (conform variantei din lucrare precedenta) și
prototipurile funcțiilor care asigură operațiunile de prelucrare a listei simplu
inlantuite.

2. Fișier cu extensia .cpp (sau .c) care contine codurile (implementarile)


tuturor functiilor declarate în fișierul antet.

3. Fișierul utilizatorului - programul cu funcția main () pentru prelucrarea listei


simplu inlantuite cu afisarea meniului de optiuni pe ecran, si anume:
pentru lucrare de laborator 2- crearea listei simplu inlantuite in memoria
dinamica, introducerea informatiei despre elementele listei de la tastatura,
afisarea informatiei despre elementele listei pe ecran, cautarea elementului listei
dupa unui cimp informational, modificarea cimpurilor elementului listei,
interschimbarea a 2 elemente listei, determinarea lungimei listei, sortarea
elementelor listei dupa unui cimp, eliberarea memoriei dinamice alocate pntru
lista, ieșire din program;
pentru lucrare de laborator 3- adaugarea unui element nou la sfirsitul listei,
adaugarea unui element nou la începutul listei, inserarea unui element nou in lista
dupa elementul indicat, inserarea unui element nou in lista inainte elementul
indicat, stergerea unui element al listei, divizarea listei simplu inlantuite in doua
liste separate, unirea a 2 liste simlu inlantuite intr-o singura lista, scrierea
informatiei despre elementele listei in fisier, citirea informatiei despre elementele
listei din fișier, ieșire din program.
Mersul lucrării:

Noţiuni principale din teorie şi metode folosite:

O listă simplu înlănţuită este o colecţie de noduri aşezate într-o ordine liniară (dar
NU în locaţii succesive din memorie - aşa cum se întâmplă la vectori). Fiecare nod
are cel puţin un pointer către următorul nod, pe care îl vom numi next. Primul nod
se numeşte head,. Lista se numeşte simplu înlănţuită deoarece fiecare nod
memorează un singur pointer către următorul nod. Spre deosebire de vectori, lista
nu are o mărime fixă. Poate fi redimensionată prin adăugarea sau ştergerea
nodurilor. Un nod este ca un obiect (item) care conţine atât informaţia pe care vreţi
s-o stocaţi cât şi legătura către următorul obiect.

Datorită faptului ca elementele listei sunt stocate în diferite părți ale memoriei
calculatorului sunt ușurate anumite operații cu lista, de exemplu inserarea sau
ștergerea unui element al listei nu necesită mișcarea celorlalte elemente pentru a
face loc sau pentru a strînge lista, așa cum se întîmplă la vectori de exemplu.

Exemplu de bază de date în formă de listă simplu înlănțuită:

typedef struct film


{ char denumirea [50];
int anul ;
int pretul ;
int durata;
int nota;
struct film*next;
} film;
film* head=NULL;
Fisierul tablou.h
typedef struct film
{ char denumirea [50];
int anul ;
int pretul ;
int durata;
int nota;
struct film*next;
} film;
film* head=NULL;
int create(int n);
Functia de creare a listei simplu inlantuita necirculara,primenste ca
paramentru „n” care este numarul de elemente care urmeaza a fi
alocate.
void read();
Funcita de introducere a elementelor in lista simplu inlantuita
necirculara.
film* search(char* s);
Functia de cautare in lista simplu inlantuita necirculara dupa
un cimp al structurii.Primeste ca parametru adresa la string-ul
introdus de utilizator si returneaza elementele gasite.
void show_search();
Funcita de afisarea elementelor cautate cu ajutorul functiei
search(char*);
void show(film* head);
Funtia de afisarea tuturor elemente din lista simplu inlantuita
necirculara avind ca paramentru capul listei.
void swap(film* a,film* b);
Functia de interschimbarea a doua elemente intre ele in lista
simplu inlantuita necirculara avind 2 parametri fiind elemente a
listei.
void sort();
Functia de sortare dupa pret(cimp al structurii).
int length();
Functia care determina lungimea listei simplu inlantuite
necirculare returneaza o valoare de tip int care reprezinta
lungimea listei.
film* end();
Funtia care determina care este ultimul elemente din lista
simplu inlantuita necirculara returnind adresa acestui element.
void add_after_id(int id);
Functia de adaugare a elementelor dupa indicele indicat de
utilizator in lista simplu inlantuita necirculara,are ca
paramentru indicele tastat de utilizator.
void add_before_id(int id);
Functia de adaugare a elementelor inainte de indicele indicat de
utilizator in lista simplu inlantuita necirculara,are ca
paramentru indicele tastat de utilizator.

void add_to_end();
Functia de adaugare a elementelor la sfirsit de lista simplu
inlantuita necirculara.
void delete_id(int id);
Funcita de stergere a unui element din lista simplu inlantuita
necirculara.
void devide(int id,film** head2);
Functia care devizeaza lista in doua liste,are 2
parametri,primul ste o variabila de tip int care reprezinta
indicile deunde lista v-a fi devizata,ia al doilea este adresa
elementului care urmeaza sa fie capul listei 2*/
void join(film** head2);
Functia de unire a listei in doua,are ca parametru adresa
elementului care este capul listei 2.
void modif(int id);
Funcita de modificarea unui element din lista simplu inlantuita
necirculara,avind ca parametru o variabila de tip int care este
indicile elementului care urmeaza a fi modificat.
void save(char* s);
Funcitia de salvare a informatiei din lista simplu inlantuita
necirculara in fisier,are ca paramentru adresa la string-ul
introdus de utilizator care reprezinta numele fisierului.
void load(char* s);
Funcitia de incarcare a informatiei din fisier in lista simplu
inltantuita necirculare,are ca paramentru adresa la string-ul
introdus de utilizator care reprezinta numele fisierului.
void freem();
Funcita de eliberearea memoriei,distrugerea listei simplu
inlantuite necirculare.
typedef struct specialitate
{ char denumirea [50];
int credite ;
int ore ;
int semestru;
int nota;
struct specialitate*next;
} specialitate;

int create(int n);


void read();
specialitate* search(char* s);
void show_search();
void show(specialitate* head);
void swap(specialitate* a,specialitate* b);
void sort();
int length();
specialitate* end();
void add_after_id(int id);
void add_before_id(int id);
void add_to_end();
void delete_id(int id);
void devide(int id,specialitate** head2);
void join(specialitate** head2);
void modif(int id);
void save(char* s);
void load(char* s);
void freem();
Fisierul tablou.cpp
#include "speci.h"
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

specialitate * head=NULL;
int create(int n)
{
int i;
specialitate *c,*p;
for(i=0;i<n;i++)
{
c=(specialitate*)malloc(sizeof(specialitate));
if(c == NULL) return 0;
if(i == 0)
{
head=c;
p=c;
}
else
{
p->next=c;
p=c;
}
}
p->next=NULL;
return 1;
}

void read()
{
specialitate *c=head;
int i=0;
while(c)
{
printf("\n****************************************\n\n");
printf("Introdu datele specialitateului %d\n",i+1);
printf("Denumirea: ");
scanf("%s",&c->denumirea);
printf("credite lansarii: ");
scanf("%d",&c->credite);
printf("ore: ");
scanf("%d",&c->ore);
printf("semestrul: ");
scanf("%d",&c->semestru);
printf("nota: ");
scanf("%d",&c->nota);
c=c->next;
i++;
}
}

void show(specialitate* head)


{
specialitate* c=head;
int i=0;
while(c)
{
printf("****************************************\n\n");
printf("Datele specialitateului: %d\n",i+1);
printf("Denumirea: %s\n",c->denumirea);
printf("credite: %d\n",c->credite);
printf("ore: %d\n",c->ore);
printf("semestrul: %d\n",c->semestru);
printf("Nota: %d\n\n",c->nota);
c=c->next;
i++;
}
}

void show_search(char* s)
{
specialitate *c=head;
int i=0,k=0;
while(c)
{
if(strcmp(s,c->denumirea)==0)
{
printf("****************************************\n\n");
printf("Datele specialitateului: %d\n",i+1);
printf("Denumirea: %s\n",c->denumirea);
printf("credite: %d\n",c->credite);
printf("ore: %d\n",c->ore);
printf("semestrul: %d\n",c->semestru);
printf("Nota: %d\n\n",c->nota);
k++;
}
c=c->next;
i++;
}
if(k==0)
printf("Elementul nu a fost gasit!\n");
}

specialitate* search(char* s)
{
specialitate* c=head;
int k=0;
while(c)
{
if(strcmp(s,c->denumirea)==0)
{
return c;
k++;
}
c=c->next;
}
if(k==0)
{
printf("Nu exista asa specialitate!\n");
}
return NULL;
}

void swap(specialitate *a,specialitate *b)


{
specialitate t,*na,*nb;
na=a->next;
nb=b->next;
t=*a;
*a=*b;
*b=t;
a->next=na;
b->next=nb;
}

int lenght()
{
specialitate *c=head;
int i=0;
while(c)
{
i++;
c=c->next;
}
return i;
}

void sort()
{
specialitate *a,*b;
int i,k,l;
l=lenght();
for(i=0;i<l-1;i++)
{
a=head;
b=a->next;
for(k=0;k<l-1-i;k++)
{
if(a->nota < b->nota)
{
swap(a,b);
}
a=a->next;
b=b->next;
}
}
}

specialitate* end()
{
specialitate* c;
c=head;
while(c->next)
{
c=c->next;
}
return c;
}

void modif(int id)


{
specialitate* c=head;
int i=0;
while(c)
{
if(i+1 == id)
{
printf("Datele specialitateului %d pentru modificare:\n",i+1);
printf("Denumirea: ");
scanf("%s",&c->denumirea);
printf("credite: ");
scanf("%d",&c->credite);
printf("ore: ");
scanf("%d",&c->ore);
printf("semestru: ");
scanf("%d",&c->semestru);
printf("Nota: ");
scanf("%d",&c->nota);
}
c=c->next;
i++;
}
}

void add_after_id(int id)


{
specialitate *c=head,*p;
int i=0;
while(c){
if(i == id-1){
p=c;
c=(specialitate*)malloc(sizeof(specialitate));
printf("\n****************************************\n\n");
printf("Introdu datele specialitateului %d\n",i+2);
scanf("%s",&c->denumirea);
printf("credite: ");
scanf("%d",&c->credite);
printf("ore: ");
scanf("%d",&c->ore);
printf("semestru: ");
scanf("%d",&c->semestru);
printf("Nota: ");
scanf("%d",&c->nota);
c->next=p->next;
p->next=c;
break;
}
i++;
c=c->next;
}
}

void add_before_id(int id){


specialitate *c=head,*p;
int i=0;
while(c){
if(i == id-1){
p=c;
c=(specialitate*)malloc(sizeof(specialitate));
printf("\n****************************************\n\n");
printf("Introdu datele specialitateului %d\n",i-2);
scanf("%s",&c->denumirea);
printf("credite: ");
scanf("%d",&c->credite);
printf("ore: ");
scanf("%d",&c->ore);
printf("semestru: ");
scanf("%d",&c->semestru);
printf("Nota: ");
scanf("%d",&c->nota);
if(p == head){
c->next=head;
head=c;
break;
}
else {
c->next=p;
i=0;
p=head;
while(p){
if(i == id-2){
p->next=c;
}
i++;
p=p->next;
}
break;
}
}
i++;
c=c->next;
}
}

void add_to_end(){
specialitate *c=head,*p;
while(c){
if(c->next == NULL){
p=c;
c=(specialitate*)malloc(sizeof(specialitate));
printf("\n****************************************\n\n");
printf("Introdu datele specialitateului\n");
scanf("%s",&c->denumirea);
printf("credite: ");
scanf("%d",&c->credite);
printf("ore: ");
scanf("%d",&c->ore);
printf("semestrul: ");
scanf("%d",&c->semestru);
printf("Nota: ");
scanf("%d",&c->nota);
p->next=c;
c->next=NULL;
break;
}
c=c->next;
}
}

void delete_id(int id){


specialitate *c=head,*p;
int i=0;
while(c){
if(i == id-1){
if(c == head){
head=c->next;
free(c);
break;
} else if(c->next == NULL){
p=head;
while(p){
if(p->next == c){
free(c);
p->next=NULL;
break;
}
p=p->next;
}
} else {
p=head;
while(p){
if(p->next == c){
p->next=c->next;
free(c);
break;
}
p=p->next;
}
}
}
i++;
c=c->next;
}
}

void devide(int id,specialitate** head2){


specialitate *c=head;
int i=0;
while(c){
if(i == id-1){
*head2=c->next;
c->next=NULL;
break;
}
i++;
c=c->next;
}
}

void join(specialitate** head2){


specialitate *c=head;
while(c){
if(c->next == NULL){
c->next=*head2;
break;
}
c=c->next;
}
*head2=NULL;
}
void freem()
{
specialitate *c=head,*p;
while(c)
{
p=c;
c=c->next;
free(p);
if(c == NULL)
{
break;
}
}
head=NULL;
}

void save(char* fname)


{
specialitate*c=head;
FILE *txt=fopen(fname,"w");
while(c)
{
fprintf(txt,"%s %d %d %d %d",c->denumirea,c->credite,c->ore,c-
>semestru,c->nota);
if(c->next != NULL)
{
fprintf(txt, "\n");
}
c=c->next;
}
fclose(txt);
}

void load(char* fname)


{
specialitate* c,*p;
int i=0;
FILE *txt=fopen(fname,"r");
if(!txt)
{
printf("Fisierul nu exista!\a\n");
}
while(!feof(txt))
{
c=(specialitate*)malloc(sizeof(specialitate));
if(c == NULL)
{
printf("\aMemoria nu a fost alocata\n");
}
if(i == 0)
{
head=c;
}
else
{
p->next=c;
}
p=c;
fscanf(txt,"%s%d%d%d%d",&c->denumirea,&c->credite,&c->ore,&c-
>semestru,&c->nota);
i++;
if(p==NULL){
break;
}
c->next=NULL;}
fclose(txt);
}
Fisierul main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "speci.cpp"
int main()
{
specialitate *a=NULL;
specialitate *b=NULL;
specialitate *head2=NULL;;
char a1[100];
char b1[100];
char srch[100];
char savef[100];
char loadf[100];
int n;
int m;
int com1;
int mod;
int id_devide;
int id_before;
int id_after;
int id_delete;
while(1)
{
printf("-----------------------Creare-----------------------\n");
printf("1.Crearea listei si introducerea datelor manual\n");
printf("2.Crearea listei si introduucerea datelor din
fisier\n\n");
printf("---------------------Preaucrare---------------------\n");
printf("3.Afisarea listei\n");
printf("4.Sortarea listei dupa pret\n");
printf("5.Modificarea unui element\n");
printf("6.Interschimbarea elementelor\n");
printf("7.Cautarea unui element\n");
printf("8.Devizarea elementelor in doua liste\n");
printf("9.Unirea a doua liste cu elemente\n\n");
printf("-----------------Adaugare\\Stergere------------------\n");
printf("10.Adaugarea elementuui inaintea indicelui\n");
printf("11.Adaugarea elementului dupa indice\n");
printf("12.Adaugarea elementului la sfirsitul listei\n");
printf("13.Stergea unui element\n\n");
printf("--------------------Salvare\\Iesire------------------\n");
printf("14.Salvarea in fisier\n");
printf("15.Salvare si Iesire\n");
printf("----------------------------------------------------\n");
printf("\nDati comanda\n>");
scanf("%d",&com1);
switch(com1)
{
case 1:
if(head)
{
printf("Memoria este deja alocata\n");
break;
}
printf("Dati numarul de elemente in lista\n>");
scanf("%d",&n);
create(n);
read();
if(head)
{
printf("Lista a fost creata cu
succes!\a\n");
break;
}
case 2:
if(head){
printf("Memoria este deja alocata\n");
break;
}
printf("Dati numele fisierului\n>");
fflush(stdin);
gets(loadf);
strcat(loadf,".txt");
load(loadf);
printf("\aIntroducerea a fost efectuata cu
succes!\n");
break;
case 3:
if(!head)
{
printf("Lista nu exista!\a\n");
break;
}
show(head);
break;
case 4:
if(!head)
{
printf("Lista nu exista!\a\n");
break;
}
sort();
printf("Lista a fost sortata cu succes!\a\n");
break;
case 5:
if(!head)
{
printf("Lista nu exista!\a\n");
break;
}
show(head);
printf("\nDati indicile elementului pentru
modificare\n>");
scanf("%d",&mod);
modif(mod);
printf("Modificara a avut loc cu succes!\a\n");
break;
case 6:
if(!head)
{
printf("Lista nu exista!\a\n");
break;
}
show(head);
printf("Dati numele primului element pentru
interschimbare\n>");
fflush(stdin);
gets(a1);
a=search(a1);
printf("Dati numele primului element pentru
interschimbare\n>");
fflush(stdin);
gets(b1);
b=search(b1);
swap(a,b);
printf("Interschimbarea a avut loc cu
succes!\a\n");
break;
case 7:
if(!head)
{
printf("Lista nu exista!\a\n");
break;
}
printf("Dati denumirea\\modelul\\originea
pentru cautare\n>");
fflush(stdin);
gets(srch);
show_search(srch);
break;
case 8:
if(!head)
{
printf("Lista nu exista!\a\n");
break;
}
show(head);
printf("\nIntrodu indicile de unde lista v-a fi
despartita\n");
scanf("%d",&id_devide);
if(lenght() > 1 && id_devide>0 && id_devide <
lenght()){
devide(id_devide,&head2);
}
printf("Devizarea a fost efectuata cu
succes!\a\n");
show(head);
show(head2);
break;
case 9:
if(!head){
printf("Lista nu exista!\a\n");
break;
}
if(head2){
join(&head2);
printf("Unirea a avut loc cu succes\n");
}
else {
printf("\aMai intii lista trebuie
despartita!\n");
}
break;
case 10:
if(!head){
printf("Lista nu exista!\a\n");
break;
}
show(head);
printf("\nIntrodu numarul de ordine:\n");
scanf("%d",&id_before);
if(id_before > 0 && id_before <= lenght() ){
add_before_id(id_before);
}
else {
printf("\aAti introdus un numar iesit din
intervalul existent\n");
}
printf("Adaugarea s-a efectuat cu
succes!\a\n");
break;
case 11:
if(!head){
printf("Lista nu exista!\a\n");
break;
}
show(head);
printf("\nIntrodu numarul de ordine:\n");
scanf("%d",&id_after);
if(id_after > 0 && id_after <= lenght() ){
add_after_id(id_after);
}
else {
printf("\aAti introdus un numar iesit din
intervalul existent\n");
}
printf("Adaugarea s-a efectuat cu
succes!\a\n");
break;
case 12:
if(!head){
printf("Lista nu exista!\a\n");
m=1;
break;
}
add_to_end();
printf("Adaugarea s-a efectuat cu
succes!\a\n");
break;
case 13:
if(!head){
printf("Lista nu exista!\a\n");
break;
}
show(head);
printf("Dati indicele elementului pentru
stergere\n");
scanf("%d",&id_delete);
delete_id(id_delete);
printf("Stergerea a fost efectuata cu
succes!\a\n");
break;
case 14:
printf("Dati numele fisierului\n>");
fflush(stdin);
gets(savef);
strcat(savef,".txt");
save(savef);
printf("\aSalvarea a fost efectuata cu
succes!\n");
break;
case 15:
if(head)
{
printf("Dati numele fisierului\n>");
fflush(stdin);
gets(savef);
save(savef);
printf("\aSalvarea a fost efectuata cu
succes!\n");
freem();
exit(1);
}
break;

default:
printf("Ati introdus o tasta incorecta!\a\n");
break;
}
}
return 0;
Citirea din fisier:

Divizarea listei:
Salvarea listei in fisier:

Concluzii:
1. Au fost obținute deprinderi de creare a unei baze de date abstractizate utilizînd
lista simplu înlănțuită în limbajul C.
2. Au fost obținute deprinderi de prelucrare a listei simplu înlănțuite, adaugarea
elementelor, stergerea, afisarea, sortarea, cautarea, interschimbarea etc.
3. Au fost obținute deprinderi de salvare a datelor în fișiere și citirea datelor din
ele.
4. Au fost obținute deprinderi de creare a fișierelor antet cu extensia .h, fișierelor
cu funcții cu extensia .c și includerea lor în proiect.

Bibliografie:
1. Conspectul prelegerilor cursului Structuri de date și Algoritmi. Lector dr.,
conf. univ. M. Kulev. Chișinău: UTM, 2018.

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