Moldova
Universitatea Tehnică a Moldovei
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
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.
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
Salvarea în 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