Sunteți pe pagina 1din 17

Ministerul Educaţiei

al Republicii Moldova

Universitatea Tehnică a Moldovei


Catedra Calculatoare și Rețele

RAPORT
despre lucrarea de laborator Nr. 9
la Structuri de date şi algoritmi 

Tema: Implementarea tipului abstract de date „Listă unidirecțională” („Listă simplu înlănțuită”) în
limbajul C. Partea II

A efectuat:
st. gr. CR-191 Axenti Alina

A verificat:
Lector univ. Munteanu Silvia

Chişinău – 2021
Scopul lucrării:
Obţinerea deprinderilor practice de implementare și de utilizare a tipului abstract de date (TAD)
“Listă simplu înlanţuită” în limbajul C cu asigurarea operațiilor de prelucrare ale listei.

Sarcina (conform variantelor) :


Să se scrie trei fişiere-text în limbajul C pentru implementarea și utilizarea TAD “Listă simplu
înlanţuită” cu asigurarea operațiilor de prelucrare ale listei:

4. Fişier antet cu extensia .h, care conține specificarea structurii de date a elementului listei simplu
înlănțuite (conform variantelor) şi prototipurile funcţiilor de prelucrare a listei.
5. Fişier cu extensia .cpp sau .c, care conține implementările funcţiilor (codurile funcţiilor) declarate în
fişierul antet.
6. Fişier al utilizatorului, funcţia mаin() pentru prelucrarea listei cu afişarea la ecran a următorului
meniu de opţiuni:

1. Crearea listei în memoria dinamică.


2. Introducerea informației despre elementele listei de la tastatură.
3. Afişarea informației despre elementele listei la ecran.
4. Căutarea elementului în listă.
5. Modificarea câmpurilor unui element din listă.
6. Determinarea adresei ultimului element din listă.
7. Determinarea lungimii listei (numărul de elemente).
8. Înterschimbarea a două elemente indicate din listă.

Varianta 2. Structura Film cu câmpurile: denumirea, ţara, regizorul, genul filmului, anul.

Mersul lucrării:
Noțiuni teoretice:
•Biblioteca stdio.h conține funcții speciale pentru citirea și afișarea datelor – prin urmare instrucțiunea
de includere a acesteia va fi practic prezentă în orice program. #include <stdio.h>;
•Int-variabila simpla de tip integer(intreg);
•While-execută un bloc de instrucţiuni atâta timp cât o anumită condiţie este adevărată;
•Printf-pentru afișarea datelor;
•Scanf-pentru citirea datelor;
•If,-instrucțiune;
•Malloc-funcție de alocare are ca rezultat adresa zonei de memorie alocate (de tip void*);

Codul programului în C
Main.c
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include "film.h"

int TRUE = 1;
int main (){

//Noduri pentru divizarea listei si pentru concaternarea lor


Node *head = NULL, *b = NULL, *c = NULL;

//Variabila pentru alegerea puntului din menu


int choice;
char ch;

while ( TRUE ){

#ifdef OSisWindows
system("cls");
#else
system("clear");
#endif

choice = print_menu();

switch( choice ){
case 1 : head = create_node( input_node() );
break;

case 2 : {
printf("\nIntroduceti numarul de noduri: ");
int nodes, i;
scanf("%d", &nodes);
for (i = 0; i < nodes; i++)
add_node(&head, input_node());
}
break;

case 3 : print_list(&head);
break;

case 4 : {
char denum[30];
printf("Denumirea elementului cautat: ");
scanf("%s", denum);
search(head, denum) ? printf("Exista !") : printf("Nu exista!");
}
break;

case 5 : {
char denum[30];
printf("Denumirea elementului care doriti sa-l modificati: ");
scanf("%s", denum);
printf("Modifica !!!\n");
update_data(head, denum, input_node());
}
break;

case 6 : {
addr_last_element(&head);
}
break;

case 7 : {
printf("Lungimea listei este: %d\n", list_length(&head));
}
break;

case 8 : {
int len1, len2;
printf("Introduceti orele de lucru elementelor care doriti sa le interschimbati: ");
scanf("%d %d", &len1, &len2);
switch_2_elements(&head, len1, len2);
}
break;

case 9 : {
sort_list(&head);
printf("Lista a fost sortata!\n");
}
break;

case 10: {
add_node(&head, input_node());
printf("Elementul a fost adaugat la sfarsitul listei !\n");
}
break;

case 11: {
push(&head, input_node());
printf("Elementul a fost adaugat la inceputul listei !\n");
}
break;

case 12: {
int nr;
printf("Pozitia elementului dupa care doriti sa adaugati: ");
scanf("%d", &nr);
int i;
Node * curr = head;
for(i = 0; i < nr; i++){
curr = curr -> next;
}
insert_after(curr, input_node());
printf("Adaugat ! \n");
}
break;

case 13: {
int nr;
printf("Pozitia elementului inaitea caruia doriti sa adaugati: ");
scanf("%d", &nr);
int i;
Node * curr = head;
for(i = 0; i < nr; i++){
curr = curr -> next;
}
push(&curr, input_node());
printf("Adaugat!\n");
}
break;

case 14: {
char denum[30];
printf("Introduceti denumirea elementului care doriti sa-l stergeti: ");
scanf("%s", denum);
delete_node(&head, denum);
printf("Adaugat!\n");
}
break;

case 15: {
split(head, &b, &c);
printf("Prima lista!\n_-1-_-1-_-1-_-1-_\n");
print_list(&b);
printf("\nA doua lista!\n_-2-_-2-_-2-_-2-_\n");
print_list(&c);
}
break;

case 16: {
concatenate(b, c);
printf("Listele au fost concatenate!");
print_list(&b);
}
break;

case 17: {
char file_name[30];
printf("Numele fisierului in care doriti sa salvati info: ");
scanf("%s", file_name);
write_to_file(&head, file_name);
}
break;

case 18: {
char file_name[30];
printf("Numele fisierului din care doriti sa cititi: ");
scanf("%s", file_name);
read_from_file(file_name);
}
break;

case 19: {
delete_list(&head);
delete_list(&b);
delete_list(&c);
printf("\nMemoria a fost eliberata!!!\n\n");
}
break;

case 0 : TRUE = 0;
break;
}

printf("Pentru a continua tastati ENTER !");


getchar();
getchar();

}
return 0;
}

Film.c
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include "film.h"

#define true 1
#define false !true

int print_menu(){
printf("\n\n\t\t#########__MENU__#########\n\n\n");
printf("\t#| 1 |-=Crearea listei in memoria dinamica=-\n");
printf("\t#| 2 |-=Introducerea informatiei de la tastatura=-\n");
printf("\t#| 3 |-=Afisarea informatiei din lista=-\n");
printf("\t#| 4 |-=Cautarea elementului in lista=-\n");
printf("\t#| 5 |-=Modificare unui element din lista=-\n");
printf("\t#| 6 |-=Adresa ultimului element din lista=-\n");
printf("\t#| 7 |-=Lungimea listei=-\n");
printf("\t#| 8 |-=Interschimbarea a doua elemente=-\n");
printf("\t#| 9 |-=Sortarea listei=-\n");
printf("\t#|10 |-=Adaugarea unui element la sfarsit=-\n");
printf("\t#|11 |-=Adaugarea unui element la inceputul listei=-\n");
printf("\t#|12 |-=Inserarea unui element dupa elementul indicat=-\n");
printf("\t#|13 |-=Inserarea unui element inaitea elementului indicat=-\n");
printf("\t#|14 |-=Stergerea elementului indicat din lista=-\n");
printf("\t#|15 |-=Deviderea listei in 2 liste=-\n");
printf("\t#|16 |-=Concatenarea a doua liste=-\n");
printf("\t#|17 |-=Salvarea listei in fisier=-\n");
printf("\t#|18 |-=Citirea din fisier=-\n");
printf("\t#|19 |-=Eliberarea memoriei=-\n");
printf("\t#| 0 |-=Iesirea din program=-\n\n\n");

int choice = -1;


printf("Introduceti numarul pentru puntul dorit din menu: ");

scanf("%d", &choice);

while(choice < 0 || choice > 19){


printf("Numarul trebuie sa fie < 19 si > 0: ");
scanf("%d", &choice);
}

return choice;
}

Node* create_node (Film a){

Node * head = (Node*)malloc( sizeof(Node) );

strcpy(head->element.denumirea, a.denumirea);
strcpy(head->element.tara, a.tara);
strcpy(head->element.regizorul, a.regizorul);

head->element.anul = a.anul;
head->element.genul_filmului = a.genul_filmului;

head -> next = NULL;

return head;
}

Film input_node(){

Film a;

printf("Denumirea: ");
scanf("%s", a.denumirea);
printf("tara: ");
scanf("%s", a.tara);

printf("regizor: ");
scanf("%s", a.regizor);

printf("anul: ");
scanf("%d", &a.anul);

printf("genul_filmului: ");
scanf("%d", &a.genul_filmului);

printf("\n\n");

return a;
}

void print_list(Node ** head_ref){

Node * temp = *head_ref;

while (temp != NULL)


{
printf("DENUMIREA: --- %s\n", temp->element.denumirea);
printf("tara: --- %s\n", temp->element.tara);
printf("regizor: --- %s\n", temp->element.regizor);
printf("anul: --- %d\n", temp->element.anul);
printf("genul_filmului: --- %d\n\n", temp->element.genul_filmului);

temp = temp->next;
}
}

//Adauga la sfarsitul listei un nou element


void add_node(Node ** head_ref, Film a){

Node * new_node = create_node(a);


new_node -> next = NULL;

Node* last = *head_ref;

if(*head_ref == NULL){
*head_ref = new_node;
return;
}

while(last->next!=NULL)
last = last->next;
last->next = new_node;
return;
}

//Adauga un nou element la inceputul listei


void push(Node** head_ref, Film new_data)
{
Node* new_node = (Node*) malloc(sizeof(Node));

new_node->element = new_data;

new_node->next = (*head_ref);

(*head_ref) = new_node;
}

void insert_after(Node* prev_node, Film new_data)


{
if (prev_node == NULL)
{
printf("the given previous node cannot be NULL");
return;
}

Node* new_node =(Node*) malloc(sizeof(Node));

new_node->element = new_data;

new_node->next = prev_node->next;

prev_node->next = new_node;
}

void delete_node(Node **head_ref, char denum[]){

if (*head_ref == NULL)
return;

Node* temp = *head_ref;

if ( !strcmp( temp->element.denumirea, denum) )


{
*head_ref = temp->next;
free(temp);
return;
}
for (int i=0; temp!=NULL && !strcmp( temp->element.denumirea, denum); i++)
temp = temp->next;

if (temp == NULL || temp->next == NULL)


return;

Node *next = temp->next->next;

free(temp->next);

temp->next = next;

void delete_list(Node** head_ref){


Node* current = *head_ref;
Node* next;

while (current != NULL)


{
next = current->next;
free(current);
current = next;
}

*head_ref = NULL;
}

int search(Node* head, char denum[])


{
Node* current = head;
while (current != NULL)
{
if (!strcmp(current->element.denumirea, denum))
return true;
current = current->next;
}
return false;
}

void update_data(Node* head, char old[], Film new) {

if(head==NULL) {
printf("Linked List not initialized");
return;
}

Node * current;
current = head;
while(current->next!=NULL) {
if(!strcmp(current->element.denumirea, old)) {
current->element = new;
return;
}

current = current->next;
}
}

int list_length(Node ** head_ref){

int count = 0;

Node * temp = *head_ref;

if(temp == NULL){
return count;
}

while(temp!=NULL){
count++;
temp = temp->next;
}

return count;
}

void addr_last_element(Node ** head_ref){

Node* temp = *head_ref;

while(temp->next != NULL){
temp = temp->next;
}

printf("\n%p\n", &temp);
}

void switch_2_elements(Node** head_ref, int x, int y){

if (x == y) return;

Node *prevX = NULL, *currX = *head_ref;


while (currX && currX -> element.anul != x)
{
prevX = currX;
currX = currX->next;
}

Node *prevY = NULL, *currY = *head_ref;


while (currY && currY->element.anul != y)
{
prevY = currY;
currY = currY->next;
}

if (currX == NULL || currY == NULL)


return;

if (prevX != NULL)
prevX->next = currY;
else
*head_ref = currY;

if (prevY != NULL)
prevY->next = currX;
else
*head_ref = currX;

Node *temp = currY->next;


currY->next = currX->next;
currX->next = temp;
}

void split(Node* source, Node** frontRef, Node** backRef)


{
int len = list_length(&source);
if (len < 2)
{
*frontRef = source;
*backRef = NULL;
return;
}

Node* current = source;

int hop_count = (len - 1) / 2;


int i;
for (i = 0; i < hop_count; i++ )
current = current->next;

*frontRef = source;
*backRef = current->next;
current->next = NULL;
}
void concatenate(Node * a, Node * b){
if( a != NULL && b!= NULL )
{
if (a->next == NULL)
a->next = b;
else
concatenate(a->next,b);
}
else
{
printf("Either a or b is NULL\n");
}
}

Node* ssort( Node* a, Node* b)


{
Node* result = NULL;

if (a == NULL)
return (b);
else if (b == NULL)
return (a);

if (a->element.genul_filmului <= b->element.genul_filmului) {


result = a;
result->next = ssort(a->next, b);
}
else {
result = b;
result->next = ssort(a, b->next);
}
return (result);
}

void sort_list(Node** head_ref)


{
Node* head = *head_ref;
Node* a;
Node* b;

if ((head == NULL) || (head->next == NULL)) {


return;
}

split(head, &a, &b);

sort_list(&a);
sort_list(&b);
*head_ref = ssort(a, b);
}

void write_to_file(Node ** head_ref, char file_name[])


{
FILE * fptr;
fptr = fopen(file_name, "w");
Node * iterator = *head_ref;

if(fptr==NULL)
{
printf("Error\n");
}

else
{
while(iterator!= NULL)
{
fprintf(fptr, "\nDENUMIREA: %s\ntara: %s\nregizor: %s\ngenul_filmului: %d\nanul: %d\n\n",
iterator->element.denumirea,
iterator->element.tara,
iterator->element.regizor,
iterator->element.genul_filmului,
iterator->element.anul
);
iterator= iterator->next;
}
}

fclose(fptr);
}

void read_from_file(char file_name[]){


FILE * f_in = fopen(file_name, "r");

char line[128];

while(fgets(line, sizeof(line), f_in))


printf("%s", line);
}

Film.h
#ifndef Film_H
#define Film_H

typedef struct
{
char denumirea[40];
char tara[40];
char regizor[40];
int genul_filmului;
int anul;
}Film;

typedef struct node


{
Film element;
struct node* next;
}Node;

int print_menu();
Node* create_node(Film);
Film input_node();
void print_list(Node **);
void add_node(Node**, Film);
void push(Node**, Film);
void insert_after(Node*, Film);
void delete_node(Node **, char[]);
void delete_list(Node**);
int search(Node*, char[]);
void update_data(Node*, char[], Film);
void addr_last_element(Node**);
int list_length(Node **);
void switch_2_elements(Node**, int, int);
void split(Node*, Node**, Node**);
void concatenate(Node *, Node *);
Node * ssort(Node*, Node*);
void sort_list(Node**);
void write_to_file(Node**, char*);
void read_from_file(char*);

#endif
Rezultate :
Concluzie:
În lucrarea de laborator nr.9 am scris trei fişiere-text în limbajul C pentru implementarea și utilizarea
TAD “Listă simplu înlanţuită” cu asigurarea operațiilor de prelucrare ale listei,acestea fiind un fişier
antet cu extensia .h, care conține specificarea structurii de date a elementului listei simplu înlănțuite şi
prototipurile funcţiilor de prelucrare a listei,un fişier cu extensia .cpp sau .c, care conține codurile
funcţiilor declarate în fişierul antet si ultimul fisier este al utilizatorului ,funcţia mаin() pentru
prelucrarea listei cu afişarea la ecran a următorului meniu de opţiuni: crearea listei în memoria
dinamică, introducerea informației despre elementele listei de la tastatură,afisarea informației despre
elementele listei la ecran,căutarea elementului în listă,modificarea câmpurilor unui element din
listă,determinarea adresei ultimului element din listă,determinarea lungimii listei (numărul de
elemente),interschimbarea a două elemente indicate din listă.