Sunteți pe pagina 1din 19

Ministerul Educaţiei, Culturii și Cercetării al Republicii

Moldova
Universitatea Tehnică a Moldovei

Departamentul Informatica și Ingenieria Sistemelor

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

A efectuat:
st. gr. C-171 V.Ciubotaru

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

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

Tema: Implementarea tipului de date abstract “Lista simplu înlănțuită” în C

Scopul lucrarii: Obținerea deprinderilor practice de implementare a unui tip de


date abstract (TDA) în limbajul C și anume a TDA “Lista simplu înlănțuită”

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


fișiere) și utilizarea (1 fișier – program cu functia main ) a TDA “Lista simplu
înlănțuită”:

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


listei simplu înlănțuite (conform variantei din lucrare precedentă) și
prototipurile funcțiilor care asigură operațiunile de prelucrare a listei simplu
înlănțuite.

2. Fișier cu extensia .cpp (sau .c) care conține codurile (implementarile)


tuturor funcțiilor declarate în fișierul antet.

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


simplu înlănțuite cu afișarea meniului de opțiuni pe ecran, și anume:
pentru lucrare de laborator 2- crearea listei simplu înlănțuite în memoria
dinamică, introducerea informației despre elementele listei de la tastatură,
afișarea informației despre elementele listei pe ecran, căutarea elementului listei
după un cîmp informațional, modificarea cîmpurilor elementului listei,
interschimbarea a 2 elemente listei, determinarea lungimei listei, sortarea
elementelor listei după un cîmp, eliberarea memoriei dinamice alocate pentru
lista, ieșire din program;
pentru lucrare de laborator 3- adăugarea unui element nou la sfirșitul listei,
adăugarea unui element nou la începutul listei, inserarea unui element nou în lista
după elementul indicat, inserarea unui element nou în lista inainte elementul
indicat, ștergerea unui element al listei, divizarea listei simplu înlănțuite în două
liste separate, unirea a 2 liste simplu înlănțuite într-o singură listă, scrierea
informației despre elementele listei în fișier, citirea informației 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 disciplina


{
char denumire [100];
char universitate [100];
char origine [100];
char specialitate [100];
int numaruldecredite;
struct disciplina *next;
}disciplina;
disciplina* head=NULL;

Fișierul
disciplina.h
typedef struct disciplina
{
char denumire[100];
char universitate[100];
char profesor[100];
char specialitate[100];
int
struct disciplina *next;
}disciplina;
disciplina* head=NULL;
int create(int n);
Funcția de creare a listei simplu înlănțuită necirculară,primește că paramentru „n” care este
numărul de elemente care urmează a fi alocate.
void read();
Funcția de introducere a elementelor în lista simplu înlănțuită necirculară.
disciplina* search(char* s);
Funcția de căutare în lista simplu înlănțuită necirculară după un cîmp al structurii. Primește ca
parametru adresa la string-ul introdus de utilizator și returnează elementele găsite.
void show_search();
Funcția de afișare a elementelor căutate cu ajutorul funcției search(char*);
void show(disciplina* head);
Funcția de afișarea tuturor elemente din lista simplu înlănțuită necirculară avînd ca paramentru
capul listei.
void swap(disciplina* a,disciplina* b);
Funcția de interschimbare a două elemente între ele în lista simplu înlănțuită necirculară avînd 2
parametri fiind elemente a listei.
void sort();
Funcția de sortare dupa numărul de credite (cîmp al structurii).
int length();
Funcția care determina lungimea listei simplu înlănțuite necirculare returnează o valoare de tip
int care reprezintă lungimea listei.
disciplina* end();
Funcția care determina care este ultimul elemente din lista simplu înlănțuită necirculară returnînd
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);
Funcția de adăugare a elementelor înainte de indicele indicat de utilizator în lista simplu
înlănțuită necirculară, are că paramentru indicele tastat de utilizator.
void add_to_end();
Funcția de adăugare a elementelor la sfîrșit de lista simplu înlănțuită necirculară.
void delete_id(int id);
Funcția de ștergere a unui element din lista simplu înlănțuită necirculară.
void devide(int id,disciplina** head2);
Funcția care devizează lista în două liste, are 2 parametri,primul este o variabilă de tip int care
reprezintă indicile de unde lista v-a fi devizată, ia al doilea este adresa elementului care urmează
să fie capul listei 2*/
void join(disciplina** head2);
Funcția de unire a listei în două, are ca parametru adresa elementului care este capul listei 2.
void modif(int id);
Funcția de modificare a unui element din lista simplu înlănțuită necirculară, avînd ca parametru o
variabilă de tip int care este indicile elementului care urmează a fi modificat.
void save(char* s);
Funcția de salvare a informației din lista simplu înlănțuită necirculară în fișier,are ca paramentru
adresa la string-ul introdus de utilizator care reprezintă numele fișierului.
void load(char* s);
Funcția de încărcare a informației din fișier în lista simplu înlănțuită necirculare, are ca
paramentru adresa la string-ul introdus de utilizator care reprezintă numele fișierului.
void freem();
Funcția de eliberearea memoriei, distrugerea listei simplu înlănțuite necirculare.
Fișierul
disciplina.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "disciplina.h"
int create(int n)
{
int i;
disciplina *c,*p;
for(i=0;i<n;i++)
{
c=(disciplina*)malloc(sizeof(disciplina));
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()
{
disciplina *c=head;
int i=0;
while(c)
{
printf("\n****************************************\n\n");
printf("Introdu datele disciplinei %d\n",i+1);
printf("Denumire: ");
scanf("%s",&c->denumire);
printf("Universitatea: ");
scanf("%s",&c->universitatea);
printf("Profesor: ");
scanf("%s",&c->profesor);
printf("Specialitatea: ");
scanf("%s",&c->specialitatea);
printf("Numarul de credite: ");
scanf("%d",&c->numaruldecredite);
c=c->next;
i++;
}
}
void show(disciplina* head)
{
disciplina* c=head;
int i=0;
while(c)
{
printf("****************************************\n\n");
printf("Datele masinii: %d\n",i+1);
printf("Denumire: %s\n",c->denumire);
printf("Universitatea: %s\n",c->universitatea);
printf("Profesor: %s\n",c->profesor);
printf("Specialitatea: %s\n",c->specialitatea);
printf("Numarul de credite: %d\n\n",c->numaruldecredite);
printf("Adresa curenta: %p\n",c);
printf("Adresa elementului urmator: %p\n",c->next);
c=c->next;
i++;
}
}
void show_search(char* s)
{
disciplina *c=head;
int i=0,k=0;
while(c)
{
if((strcmp(s,c->denumire)==0) || (strcmp(s,c->universitatea)==0 ) || (strcmp(s,c-
>profesor)==0))
{
printf("****************************************\n\n");
printf("Datele masinii: %d\n",i+1);
printf("Denumire: %s\n",c->denumire);
printf("Universitatea: %s\n",c->universitatea);
printf("Profesor: %s\n",c->profesor);
printf("Specialitatea: %s\n\n",c->specialitatea);
printf("Numarul de credite: %d\n",c->numaruldecredite);
k++;
}
c=c->next;
i++;
}
if(k==0)
printf("Elementul nu a fost gasit!\n");
}
disciplina* search(char* s)
{
disciplina* c=head;
int k=0;
while(c)
{
if(strcmp(s,c->denumire)==0 || strcmp(s,c->universitatea)==0 || strcmp(s,c-
>profesor)==0)
return c;
k++;
}
c=c->next;
printf("Nu exista asa masini!\n");
return NULL ;}
void swap(disciplina *a,disciplina *b)
{
disciplina t,*na,*nb;
na=a->next;
nb=b->next;
t=*a;
*a=*b;
*b=t;
a->next=na;
b->next=nb;
}
int lenght()
{
disciplina *c=head;
int i=0;
while(c)
{
i++;
c=c->next;
}
return i;
}
void sort()
{
disciplina *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->numaruldecredite < b->numaruldecredite)
{
swap(a,b);
}
a=a->next;
b=b->next;
}
}
}
disciplina* end()
{
disciplina* c;
c=head;
while(c->next)
{
c=c->next;
}
return c;
}
void modif(int id)
{
disciplina* c=head;
int i=0;
while(c)
{
if(i+1 == id)
{
printf("Datele disciplinei pentru modificare:%d\n",i+1);
printf("Denumire: ");
scanf("%s",&c->denumire);
printf("Universitatea: ");
scanf("%s",&c->universitatea);
printf("Profesor: ");
scanf("%s",&c->profesor);
printf("Specialitatea: ");
scanf("%d",&c->specialitatea);
printf("Numarul de credite: ");
scanf("%f",&c->numaruldecredite);
}
c=c->next;
i++;
}
}
void add_after_id(int id)
{
disciplina *c=head,*p;
int i=0;
while(c){
if(i == id-1){
p=c;
c=(disciplina*)malloc(sizeof(disciplina));
printf("\n****************************************\n\n");
printf("Introdu datele disciplinei %d\n",i+2);
printf("Denumire: ");
scanf("%s",&c->denumire);
printf("Universitatea: ");
scanf("%s",&c->universitatea);
printf("profesor: ");
scanf("%s",&c->profesor);
printf("Specialitatea ");
scanf("%s",&c->specialitatea);
printf("Numarul de credite: ");
scanf("%d",&c->numaruldecredite);
c->next=p->next;
p->next=c;
break;
}
i++;
c=c->next;
}
}
void add_before_id(int id){
disciplina *c=head,*p;
int i=0;
while(c){
if(i == id-1){
p=c;
c=(disciplina*)malloc(sizeof(disciplina));
printf("\n****************************************\n\n");
printf("Introdu datele disciplinei\n");
printf("Denumire: ");
scanf("%s",&c->denumire);
printf("Universitatea: ");
scanf("%s",&c->universitatea);
printf("profesor: ");
scanf("%s",&c->profesor);
printf("Specialitatea ");
scanf("%s",&c->specialitatea);
printf("Numarul de credite: ");
scanf("%d",&c->numaruldecredite);
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(){
disciplina *c=head,*p;
while(c){
if(c->next == NULL){
p=c;
c=(disciplina*)malloc(sizeof(disciplina));
printf("\n****************************************\n\n");
printf("Introdu datele disciplinei\n");
printf("Denumire: ");
scanf("%s",&c->denumire);
printf("Universitatea: ");
scanf("%s",&c->universitatea);
printf("profesor: ");
scanf("%s",&c->profesor);
printf("Specialitatea ");
scanf("%s",&c->specialitatea);
printf("Numarul de credite: ");
scanf("%d",&c->numaruldecredite);
p->next=c;
c->next=NULL;
break;
}
c=c->next;
}
}
void delete_id(int id){
disciplina *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,disciplina** head2){
disciplina *c=head;
int i=0;
while(c){
if(i == id-1){
*head2=c->next;
c->next=NULL;
break;
}
i++;
c=c->next;
}
}
void join(disciplina** head2){
disciplina *c=head;
while(c){
if(c->next == NULL){
c->next=*head2;
break;
}
c=c->next;
}
*head2=NULL;
}

void freem()
{
disciplina *c=head,*p;
while(c)
{
p=c;
c=c->next;
free(p);
if(c == NULL)
{
break;
}
}
head=NULL;
}
void save(char* fname)
{
disciplina*c=head;
FILE *txt=fopen(fname,"wt");
while(c)
{
fprintf(txt,"%s%s%s%s%d",&c->denumire,&c->universitatea,&c->profesor,&c-
>specialitatea,&c->numaruldecredite);
if(c->next != NULL)
{
fprintf(txt, "\n");
}
c=c->next;
}
fclose(txt);
}
void load(char* fname)
{
disciplina* c,*p;
int i=0;
FILE *txt=fopen(fname,"r");
if(!txt)
{
printf("Fisierul nu exista!\a\n");
}
while(!feof(txt))
{
c=(disciplina*)malloc(sizeof(disciplina));
if(c == NULL)
{
printf("\aMemoria nu a fost alocata\n");
}
if(i == 0)
{
head=c;
p=c;
}
else
{
p->next=c;
p=c;
}
fscanf(txt,"%s%s%s%s%d",&c->denumire,&c->universitatea,&c->profesor,&c-
>specialitatea,&c->numaruldecredite);
i++;

p->next=NULL;
fclose(txt);
}
}

Fișierul
main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "disciplina.cpp"
int main()
{
disciplina *a=NULL;/*element pentru sortare/interschimbare*/
disciplina *b=NULL;/*element pentru sortare/interschimbare*/
disciplina *head2=NULL;;/*element cap pentru divizare*/
char a1[100];/*string 1 pentru interschimbare*/
char b1[100];/*string 2 pentru interschimbare*/
char srch[100];/*string pentru cautare*/
char savef[100];/*string pentru salvare*/
char loadf[100];/*string pentru incarcare*/
int n;/*numarul de elemente in lista*/
int m;/*ciclu infinit meniu principal*/
int com1;/*indice pentru meniu pricipal*/
int mod;/*indice pentru modificare*/
int id_devide;/*indice pentru devizare*/
int id_before;/*indice pentru adaugare inaintea indicelui*/
int id_after;/*indice pentru adaugare dupa indice*/
int id_delete;/*indice pentru stergere a elemenentului*/
while(1)
{
{
system("cls");
printf("-----------------------Creare-----------------------\n");
printf("1.Crearea listei si introducerea datelor manual\n");
printf("2.Crearea listei si introducerea datelor din fisier\n\n");
printf("---------------------Prelucrare---------------------\n");
printf("3.Afisarea listei\n");
printf("4.Sortarea listei dupa numarul de credite\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 elementului 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.Iesire\n");
printf("----------------------------------------------------\n");
printf("\n Dati comanda\n>");
scanf("%d",&com1);
switch(com1)
{
case 1:
system("cls");
if(head)
{
printf("Memoria este deja alocata\n");
system("pause");
m=1;
break;
}
system("cls");
printf("Dati numarul de elemente in lista\n>");
scanf("%d",&n);
create(n);
read();
if(head)
{
system("cls");
printf("Lista a fost creata cu succes!\a\n");
system("pause");
m=1;
break;
}
case 2:
system("cls");
if(head)
{
printf("Memoria este deja alocata\n");
system("pause");
m=1;
break;
}
printf("Dati numele fisierului\n>");
fflush(stdin);
gets(loadf);
strcat(loadf,".txt");
load(loadf);
printf("\aIntroducerea a fost efectuata cu succes!\n");
m=1;
system("pause");
break;
case 3:
system("cls");
if(!head)
{
printf("Lista nu exista!\a\n");
m=1;
system("pause");
break;
}
show(head);
system("pause");
m=1;
break;
case 4:
system("cls");
if(!head)
{
printf("Lista nu exista!\a\n");
m=1;
system("pause");
break;
}
sort();
printf("Lista a fost sortata cu succes!\a\n");
system("pause");
m=1;
break;
case 5:
system("cls");
if(!head)
{
printf("Lista nu exista!\a\n");
m=1;
system("pause");
break;
}
show(head);
printf("\nDati indicile elementului pentru modificare\n>");
scanf("%d",&mod);
system("cls");
modif(mod);
printf("Modificara a avut loc cu succes!\a\n");
m=1;
system("pause");
break;
case 6:
system("cls");
if(!head)
{
printf("Lista nu exista!\a\n");
m=1;
system("pause");
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);
system("cls");
swap(a,b);
printf("Interschimbarea a avut loc cu succes!\a\n");
m=1;
system("pause");
break;
case 7:
system("cls");
if(!head)
{
printf("Lista nu exista!\a\n");
m=1;
system("pause");
break;
}
printf("Dati denumire\\universitatea\\profesor pentru cautare\n>");
fflush(stdin);
gets(srch);
show_search(srch);
m=1;
system("pause");
break;
case 8:
system("cls");
if(!head)
{
printf("Lista nu exista!\a\n");
m=1;
system("pause");
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);
m=1;
system("pause");
break;
case 9:
system("cls");
if(!head){
printf("Lista nu exista!\a\n");
m=1;
system("pause");
break;
}
if(head2){
join(&head2);
printf("Unirea a avut loc cu succes\n");
}
else {
printf("\aMai intii lista trebuie despartita!\n");
}
m=1;
system("pause");
break;
case 10:
system("cls");
if(!head){
printf("Lista nu exista!\a\n");
m=1;
system("pause");
break;
}
show(head);
printf("\nIntrodu numarul de ordine:\n");
scanf("%d",&id_before);
if(id_before > 0 && id_before <= lenght() ){
system("cls");
add_before_id(id_before);
}
else {
printf("\aAti introdus un numar iesit din intervalul existent\n");
}
system("cls");
printf("Adaugarea s-a efectuat cu succes!\a\n");
m=1;
system("pause");
break;
case 11:
system("cls");
if(!head){
printf("Lista nu exista!\a\n");
m=1;
system("pause");
break;
}
show(head);
printf("\nIntrodu numarul de ordine:\n");
scanf("%d",&id_after);
if(id_after > 0 && id_after <= lenght() ){
system("cls");
add_after_id(id_after);
}
else {
printf("\aAti introdus un numar iesit din intervalul existent\n");
}
system("cls");
printf("Adaugarea s-a efectuat cu succes!\a\n");
m=1;
system("pause");
break;
case 12:
system("cls");
if(!head){
printf("Lista nu exista!\a\n");
m=1;
system("pause");
break;
}
add_to_end();
system("cls");
printf("Adaugarea s-a efectuat cu succes!\a\n");
m=1;
system("pause");
break;
case 13:
system("cls");
if(!head){
printf("Lista nu exista!\a\n");
m=1;
system("pause");
break;
}
show(head);
printf("Dati indicele elementului pentru stergere\n");
scanf("%d",&id_delete);
delete_id(id_delete);
system("cls");
printf("Stergerea a fost efectuata cu succes!\a\n");
m=1;
system("pause");
break;
case 14:
system("cls");
printf("Dati numele fisierului\n>");
fflush(stdin);
gets(savef);
save(savef);
printf("\aSalvarea a fost efectuata cu succes!\n");
m=1;
system("pause");
break;
case 15:
system("cls");
if(head)
{
printf("\aToate operatiunile au fost efectuate cu succes!\n");
puts("GOOD BYE");
system("pause");
freem();
exit(1);
}
break;

default:
system("cls");
printf("Ati introdus o tasta incorecta!\a\n");
m=1;
system("pause");
break;
}
}
}
return 0;
}
Crearea listei și introducerea datelor manual
Citirea datelor din fișier
Afișarea listei

Sortarea

Modificare
Interschimbarea elementelor

Divizarea

Unirea

Adăugarea elementului înaintea indicelui

Adăugarea elementului după indice


Adăugarea elementului la sfîrșitul listei

Ștergerea a unui element

Salvarea în fișier

Datele din fișier

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.
UTM 2014
2. https://en.wikipedia.org/wiki/Linked_list accesat la 01.03.2018

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