Sunteți pe pagina 1din 37

Universitatea Tehnică

Facultatea de Calculatoare, Informatică și Microelectronică

Referat
la Structuri de Date și
algoritmi
Laboratorul 12
Tema: Implementarea tipului abstract de date „Arbore binar”.
Utilizarea algoritmilor recursive și stiva

A realizat: Garaz Eugeniu


Profesor: Munteanu Silvia

Chișinău
2020
Scopul lucrării: Obținerea deprinderilor practice de implementare și de utilizare a tipului
abstract de date (TAD) „Arbore binar” cu asigurarea operațiilor de prelucrare de bază ale
arborelui binar oarecare prin parcurgerea nodurilor arborelui “în lățime” și “în adâncime”,
folosind structura respectivă de date “stiva”. Obținerea deprinderilor practice de implementare și
de utilizare a tipului abstract de date (TAD) „Arbore binar” cu asigurarea operațiilor de
prelucrare de bază ale arborelui binar oarecare prin parcurgerea recursivă a nodurilor
arborelui, folosind algoritmi recursivi.

Sarcină: Să se scrie trei fișiere-text în limbajul C pentru implementarea și utilizarea TAD


„Arbore binar” cu asigurarea operațiilor de prelucrare de bază ale arborelui binar oarecare prin
parcurgerea nodurilor arborelui cu ajutorul algoritmilor recursive și stivă:
1. Fișier antet cu extensia .h, care conține specificarea structurii de date a nodului arborelui binar
(conform variantelor) și prototipurile funcțiilor de prelucrare ale arborelui binar oarecare, bazate
pe algoritmi recursive și stivă.
2. Fișier cu extensia .cpp sau .c, care conține implementările funcțiilor (codurile funcțiilor),
declarate în fișierul antet.
3. Fișiere al utilizatorului, funcția main() pentru prelucrarea arborelui binar oarecare cu afișarea
la ecran a următorului meniu de opțiuni:
1. Crearea nodurilor arborelui binar oarecare în memoria dinamică și introducerea informației
despre nodurile arborelui de la tastatură în mod interactive.
2. Afișarea informației despre nodurile arborelui la ecran.
3. Căutarea nodului în arbore.
4. Modificarea informației a unui nod din arbore.
5. Determinarea numărului de noduri.
6. Determinarea înălțimii arborelui.
7. Eliberarea memoriei alocate pentru arbore.
0. Ieșirea din program.
Varianta 6: Structura Automobil cu câmpurile: modelul, tara, data
fabricării, puterea motorului, costul.

Programul În C
Fișierul include.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//---------------------ARBORELE--------------------
typedef struct      Node {
    char            model[50];
    char            tara[50];
    char            data[50];
    float           puterea;
    float           pretul;
    struct Node     *left;
    struct Node     *right;
}                   Node;

//---------------------STIVA-----------------------
//Pentru lucrul iterativ cu arborele
typedef struct      Stiva {
 Node               *adrnod;
 struct Stiva       *prev;
}                   Stiva;
//-------------------------------------------------

//---------------------MENU------------------------
//Recursive Mode
void                showMenu();
void                showSearchMenu();
void                modificareMenu();
void                showIterativeOrRecursiveMode();
//-------------------------------------------------

//---------------------AFISARE---------------------
void                afisare(Node *head); // Afisare un element
//Recursiv
void                selectareaModurilor(Node *head); //selectarea modurilor de a
fisare
void                afisare_rsd(Node *head); // afisare rsd
void                afisare_srd(Node *head); // afisare srd
void                afisare_sdr(Node *head); // afisare sdr
void                afisare_dsr(Node *head); // afisare dsr
//Iterativ
int                 showStiva(Node *head, Stiva *top); // afisare cu ajutorul st
ivei
//-------------------------------------------------

//---------------------CAUTARE---------------------
//Recursiv
void                cautareNode(Node *head, char *str); // cautarea nodului pent
ru afisare
//Iterativ
Node                *searchStiva(Node *head, Stiva *top, char *nume); // cautare
a nodului cu ajutorul stivei
//-------------------------------------------------

//---------------------CREARE----------------------
//Recursiv
void                creare(Node *head); // crearea arborelui
//Iteretiv
Node                *createStiva(Node *head, Stiva *top);// crearea arborelui cu 
ajutorul unei stive
//-------------------------------------------------

//---------------------DETERMINARI-----------------
//Recursiv
int                 determinNrNode(Node *head); // determinarea nr de noduri a a
rborelui
int                 AB_Height(Node *head); // determinarea inaltimii arborelui
//Iterativ
int                 nrNoduriStiva(Node *head, Stiva *top);//determinarea nr de n
oduri cu stiva
//-------------------------------------------------

//---------------------MODIFICARI------------------
void                modify(Node *head); //selectaria campului pentru modificare
void                cautareNodeModif(Node *head, char *str); // gasirea nodului 
pentru modificare dupa model
//-------------------------------------------------

//---------------------DISTRUGERE------------------
//Recursiv
void                delete(Node *head); // dealocarea arborelui
//Iterativ
Node                *freeMemStiva(Node *head, Stiva *top);//dealocarea arborelui 
iterativ
//-------------------------------------------------
//---------------------AUXILIAR--------------------
Node                *pop(Stiva *top);
Stiva                 *push(Node *p, Stiva *top);
//-------------------------------------------------

Fișierul main.c
#include "include.h"

int main() {
    int     q;
    int     option;
    char    str[50];
    Node    *head;
    Node    *head1;
    Stiva   *stiva;
    Node    *search;

    while (1) {
        showIterativeOrRecursiveMode();
        printf("Alegeti optiunea: ");
        scanf("%d", &q);
        switch (q)
        {
            case 1:
                while (1)
                {
                    showMenu();
                    printf("Alegeti optiunea: ");
                    scanf("%d", &option);
                    switch (option)
                    {
                        case 1:
                            head1 = createStiva(head1, stiva);
                            break;
                        case 2:
                            showStiva(head1, stiva);
                            break;
                        case 3:
                            printf("Introduceti denumriea elementului care dorit
i sal schimbati:\n");
                            scanf("%s", str);
                            search = searchStiva(head1, stiva, str);
                            if (search != NULL) {
                                afisare(search);
                            } else {
                                printf("Nu sa gasit asa element\n");
                            }
                            break;
                        case 4:
                            printf("Introduceti denumriea elementului care dorit
i sal schimbati:\n");
                            scanf("%s", str);
                            search = searchStiva(head1, stiva, str);
                            if (search != NULL) {
                                modify(search);
                            } else {
                                printf("Nu sa gasit asa element\n");
                            }          
                        case 5:
                            printf("Numarul de noduri este %d\n", nrNoduriStiva(
head1, stiva));
                            break;
                        case 6:
                            printf("Inaltimea arborelui este %d\n", AB_Height(he
ad1));
                            break;
                        case 7:
                            head1 = freeMemStiva(head1, stiva);
                            head1 = NULL;
                            printf("Memoria so dealocat.\n");
                            break;
                        case 0:
                            if (head1 != NULL) {
                                head1 = freeMemStiva(head1, stiva);
                                if (head1 == NULL) {
                                    printf("Arborele precedent a fost sters\n");
                                }
                            }
                            printf("Ati revenit in meniul principal\n");
                            break;
                        default:
                            printf("Nu exista asa optiune!\n");
                            break;
                    }
                    if (option == 0) {
                        break;
                    }
                }
                
                break;
            case 2:
                while (1)
                {
                    showMenu();
                    printf("Alegeti optiunea: ");
                    scanf("%d", &option);
                    switch (option)
                    {
                        case 1:
                            head = (Node*)malloc(sizeof(Node));
                            creare(head);
                            if (head != NULL) {
                                printf("Arborele a fost create cu succes\n");
                            } else {
                                printf("Arborele nu a fost creat\n ERROR!\n");
                            }
                            break;
                        case 2:
                            selectareaModurilor(head);
                            break;
                        case 3:
                            printf("Dati modelul cautat\n");
                            scanf("%s", str);
                            cautareNode(head, str);
                            break;
                        case 4:
                            printf("Introduceti denumriea elementului care dorit
i sal schimbati:\n");
                            scanf("%s", str);
                            cautareNodeModif(head, str);
                            break;
                        case 5:
                            printf("Numarul de noduri este %d\n", determinNrNode
(head));
                            break;
                        case 6:
                            printf("Inaltimea arborelui este %d\n", AB_Height(he
ad));
                            break;
                        case 7:
                            delete(head);
                            printf("Memoria so dealocat.\n");
                            break;
                        case 0:
                            printf("Ati revenit in meniul principal\n");
                            break;
                        default:
                            printf("Nu exista asa optiune!\n");
                            break;
                    }
                    if (option == 0) {
                        break;
                    }
                }
                
                break;
            case 0:
                if (head != NULL) {
                    printf("Ati uitat sa distrugeti arborele\n");
                    delete(head);
                    if (head == NULL) {
                        printf("El a fost distrus reusit\n");
                    }
                }
                if (head != NULL) {
                    printf("Ceva nu so distrus ce ar fi trebuit\n");
                    return (-1);
                } else {
                    printf("Iesire reusita din program");
                    return (1);
                }
                break;
        
            default:
                printf("Nu exista asa optiune\n");
                break;
        }
    }
    return (0);
}

Fișierul auxiliar.c
#include "include.h"

Stiva     *push(Node *p, Stiva *top)
{
    Stiva *s;

    s = (Stiva*)malloc(sizeof(Stiva));
    s->prev = top;
    s->adrnod = p;
    top = s;
    return top;
}

Node    *pop(Stiva *top)
{
    Stiva   *s = top;
    Node    *p;

    top = s->prev;
    p = (Node*)malloc(sizeof(Node));
    p = s->adrnod;
    return p;
}
Fișierul afisare.c
#include "include.h"

void    afisare(Node *head) {
    printf("Numele: %s\n", head->model);
    printf("Tara: %s\n", head->tara);
    printf("Data: %s\n", head->data);
    printf("Puterea: %f\n", head->puterea);
    printf("Pretul: %f\n", head->pretul);
}

void    afisare_rsd(Node *head) {
    if (head != NULL) {
        afisare(head);
        afisare_rsd(head->left);
        afisare_rsd(head->right);
    }
}

void    afisare_srd(Node *head) {
    if (head != NULL) {
        afisare_srd(head->left);
        afisare(head);
        afisare_srd(head->right);
    }
}

void    afisare_sdr(Node *head) {
    if (head != NULL) {
        afisare_sdr(head->left);
        afisare_sdr(head->right);
        afisare(head);
    }
}

void    afisare_dsr(Node *head) {
    if (head != NULL) {
        afisare_dsr(head->right);
        afisare_dsr(head->left);
        afisare(head);
    }
}

void    selectareaModurilor(Node *head) {
    int q;

    q = -1; 
    while (q)
    {
        showSearchMenu();
        scanf("%d", &q);
        switch (q)
        {
            case 1:
                afisare_rsd(head);
                break;
            case 2:
                afisare_srd(head);
                break;
            case 3:
                afisare_sdr(head);
                break;
            case 4:
                afisare_dsr(head);
                break;
            case 0:
                printf("Iesire in meniul principal\n");
                return ;
            default:
                printf("Asa optiune nu exista\n");
                break;
        }
    }
    
}

//Iterativ
int     showStiva(Node *head, Stiva *top)
{
    Node    *p, *c;
    Stiva   *aux;

    top = NULL;
    if(!head) {
        return 0;
    }
    p = head;
    top = push(p, top);

    printf("informatia despre model\r\n");
    while(top)
    {
        p = pop(top);

        afisare(p);

        aux = top->prev;
        free(top);
        top = aux;

        c = p->right;
        if(c != NULL)
        {
            top = push(c, top);
        }
        c = p->left;
        if(c != NULL)
        {
            top = push(c, top);
        }
    }
    return -1;
}
Fișierul cautare.c
#include "include.h"

void        cautareNode(Node *head, char *str) {
    if (head != NULL) {
        if (strcmp(head->model, str) == 0) {
            afisare(head);
        } else {
            cautareNode(head->left, str);
            cautareNode(head->right, str);
        }
    }
}

void        cautareNodeModif(Node *head, char *str) {
    if (head != NULL) {
        if (strcmp(head->model, str) == 0) {
            modify(head);
        } else {
            cautareNodeModif(head->left, str);
            cautareNodeModif(head->right, str);
        }
    }
}

Node        *searchStiva(Node *head, Stiva *top, char *nume) {
    Node    *p, *c;
    Stiva   *aux;

    top = NULL;
    if(!head) {
        return NULL;
    }
    
    p = head;
    top = push(p, top);

    while(top)
    {
        p = pop(top);

        aux = top->prev;
        free(top);
        top = aux;

        if(!strcmp(p->model, nume)) {
            return(p);
        }

        c = p->right;
        if(c != NULL)
        {
            top = push(c, top);
        }

        c = p->left;
        if (c != NULL) {
            top = push(c, top);
        }
    }

    return NULL;
}

Fișierul creare.c
#include "include.h"
// Recursiv
void        creare(Node *head) {
    int i;

    printf("Dati numele:\n");
    scanf("%s", head->model);
    printf("Dati tara: \n");
    scanf("%s", head->tara);
    printf("Dati data: \n");
    scanf("%s", head->data);
    printf("Dati puterea: \n");
    scanf("%f", &head->puterea);
    printf("Dati pretul: \n");
    scanf("%f", &head->pretul);
    printf("Doriti sa create node pe dreapta(1 = True/0 = False): ");
    scanf("%d", &i);
    if (i == 1) {
        head->right = (Node*)malloc(sizeof(Node));
        creare(head->right);
    } else {
        head->right = NULL;
    }
    printf("Doriti sa creati node pe stanga(1 = True/0 = False): ");
    scanf("%d", &i);
    if (i == 1) {
        head->left = (Node*)malloc(sizeof(Node));
        creare(head->left);
    } else {
        head->left = NULL;
    }
}

void    introducereInfo(Node *head) {
    printf("Dati numele:\n");
    scanf("%s", head->model);
    printf("Dati tara: \n");
    scanf("%s", head->tara);
    printf("Dati data: \n");
    scanf("%s", head->data);
    printf("Dati puterea: \n");
    scanf("%f", &head->puterea);
    printf("Dati pretul: \n");
    scanf("%f", &head->pretul);
}

//Iterativ
Node     *createStiva(Node *head, Stiva *top)
{
    Node    *p,*c;
    Stiva   *aux;
    int     f;

    head = NULL;
    top = NULL;
    printf("Doriti sa creati radacina arborelui (1/0)\r\n");
    scanf("%d",&f);
    if(f)
    {
        c = (Node*)malloc(sizeof(Node));

        introducereInfo(c);

        top = push(c, top);
        head = c;
        while(top != NULL) {

            p = pop(top);

            printf("Doriti sa creati copilul drept al nodului %s (1/0)?\n", p-
>model);
            scanf("%d", &f);
            aux = top->prev;
            free(top);
            top = aux;
            
            if(f) {
                c = (Node*)malloc(sizeof(Node));

                introducereInfo(c);
                
                p->right = c;
                top = push(c, top);
            } else {
                p->right = NULL;
            }

            printf("Doriti sa creati copilul stang al nodului %s (1/0)?\n", p-
>model);
            scanf("%d", &f);

            if(f) {
                c = (Node*)malloc(sizeof(Node));

                introducereInfo(c);

                p->left = c;

                top = push(c, top);
            } else {

                p->left = NULL;
            }
        }
    }
    return head;
}
Fișierul delete.c
#include "include.h"

void    delete(Node *head) {
    if (head) {
        delete(head->left);
        delete(head->right);
        free(head);
    }
}

Node     *freeMemStiva(Node *head, Stiva *top)
{
    Stiva   *aux;
    
    if(!head) {
        return NULL;
    }
    top = push(head, top);
    while(top)
    {
        head = top->adrnod;
        aux = top->prev;
        free(top);
        top = aux;

        if(head->right != NULL)
        {
            top = push(head->right, top);
        }

        if(head->left != NULL)
        {
            top = push(head->left, top);
        }

        free(head);
    }
    return head;
}

Fișierul determinare.c
#include "include.h"

int         determinNrNode(Node *head) {

    
    if (head != NULL) {
        determinNrNode(head->left);
        determinNrNode(head->right);
        return (determinNrNode(head->left) + determinNrNode(head->right) + 1);
    } else {
        return (0);
    }
}

int AB_Height(Node *head) {
    int hs, hd;
    if(!head) { 
        return (-1);
    }
    hs = AB_Height(head->left);
    hd = AB_Height(head->right);
    return 1 + (hs > hd ? hs : hd);
}

int nrNoduriStiva(Node *head, Stiva *top)
{
    Node    *p,*c;
    Stiva   *aux;
    int     s=0;

    top = NULL;
    if(!head) {
        return 0;
    }
    p = head;
    top = push(p, top);
    while(top) {
        p = pop(top);
        aux = top->prev;
        free(top);
        top = aux;
        s++;
        c = p->right;
        if(c!=NULL) {
            top = push(c, top);
        }
        c = p->left;
        if(c!=NULL) {
            top = push(c, top);
        }
    }
    return s;
}
Fișierul menu.c
#include "include.h"

void        showMenu() {
    printf("-------------------------------
MENU--------------------------------\n");
    printf("[1] - Creare arborelui\n");
    printf("[2] - Afisarea arborelui creat\n");
    printf("[3] - Cautarea Nodului in arbore\n");
    printf("[4] - Modificarea informatiei unui nod din arbore\n");
    printf("[5] - Determinarea numarului de Noduri\n");
    printf("[6] - Determinarea inaltimii arborelui\n");
    printf("[7] - Eliberarea memoriei arborelui\n");
    printf("[0] - Revenirea in meniul principal\n");
    printf("------------------------------------------------------------------\n"
);
}

void        showIterativeOrRecursiveMode() {
    printf("------------------------------SELECT MODE------------------------
-\n");
    printf("[1] - Iterative Mode\n");
    printf("[2] - Recursive Mode\n");
    printf("[0] - Exit\n");
    printf("------------------------------------------------------------------\n"
);
}

void        showSearchMenu() {
    printf("-----------------------------SEARCH-
MENU--------------------------\n");
    printf("[1] - Afisarea in mod rsd\n");
    printf("[2] - Afisarea in mod srd\n");
    printf("[3] - Afisarea in mod sdr\n");
    printf("[4] - Afisarea in mod dsr\n");
    printf("[0] - Iesire in meniul principal\n");
    printf("------------------------------------------------------------------\n"
);
}

void       modificareMenu() {

    printf("-----------------------------MODIFY-
MENU--------------------------\n");
    printf("[1] - Modificarea numelui\n");
    printf("[2] - Modificarea tarii\n");
    printf("[3] - Modificarea datei\n");
    printf("[4] - Modificarea pretului\n");
    printf("[5] - modificarea puterii\n");
    printf("[0] - Iesire din meniu\n");
    printf("------------------------------------------------------------------\n"
);
    printf("Obtiunea: ");
}
Fișierul modify.c
#include "include.h"

void        modify(Node *head) {
    int q;

    while (1)
    {
        modificareMenu();
        scanf("%d", &q);
        switch (q)
        {
        case 1:
            printf("Introduceti numele nou:\n");
            scanf("%s", head->model);
            break;
        case 2:
            printf("Introduceti tara noua:\n");
            scanf("%s", head->tara);
            break;
        case 3:
            printf("Introduceti data noua:\n");
            scanf("%s", head->data);
            break;
        case 4:
            printf("Introduceti pretul nou:\n");
            scanf("%f", &head->pretul);
            break;
        case 5:
            printf("Introduceti puterea noua:\n");
            scanf("%f", &head->puterea);
            break;
        case 0:
            return ;
            break;
        default:
            break;
        }
    }
    
}

Rularea programului
Concluzie: În urma efectuării acestei lucrări am studiat cum se creează și se
prelucrează arborii binari. Am folosit două metode metoda recursivă și metoda
utilizării structurii de date stivă. În final am reușit să creăm un program care
stochează datele sub formă de arbore binar având la dispoziție două metode de
stocare cea recursivă și cu ajutorul stivei.

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