21
Universitatea Tehnic din Moldova Catedra Calculatoare TEZ DE AN la disciplina: Structuri de Date i Algoritmi Bibliotec SDA Determinarea arborilor de c utare A eleborat studentul grupei C-141: Radu A verificat conf. univ. : tefan Marin Chi in u 2015

Biblioteca SDA - BST [Binary Search Tree]

Embed Size (px)

DESCRIPTION

Biblioteca SDA - BST [Binary Search Tree]

Citation preview

  • Universitatea Tehnic din MoldovaCatedra Calculatoare

    TEZ DE ANla disciplina: Structuri de Date i Algoritmi

    Bibliotec SDADeterminarea arborilor de cutare

    A eleborat studentul grupei C-141: RaduA verificat conf. univ. : tefan Marin

    Chiinu 2015

  • Sarcina lucrrii:

    Aplica ia Bibliotec SDA Determinarea arborilor de cutare n adncime i prin cuprindere. Grafuriimplementate prin grafuri adiacente, structuri de adiacente i toate variatele posibile.

    Analiza succint a domeniului:

    Structuri de Date i Algoritmi (SDA) sunt instrumentele de baz a fiecrui programator. Efidentcunotinele i nelegerea acestui domeniu definete eficiena programelor elaborate de programator.

    Noi interacionm cu structurile de date tot timpul, iar modul cum noi o salvm, sortm, organizm estefoarte important. S lum ceva exemple din via unde organizare informaie n structuri de date neajut enorm:

    S cutm cuvintul necesar ntr-un dicionar; Hrile conin informaia geografic sub form de structuri de date organizate geometric; Bonul de plat organizeaz datele despre cumprturi n form de tabel;

    Deci domeniul Structuri de Date i Algoritmi este modul prin care salvm i organizm informaia ntr-un calculator de unde poate fi utilizat eficient.

    Descrierea principiilor:

    Pentru a salva i organiza informaia n calculator noi putem s folosim tablouri, liste i derivatele ei,arbori i derivatele lui, fisiere. Aa cum pentru noi prioritate au arborii i implementarea lor, ncontinuare vom vorbi despre ele.

    Arbori n comparaie cu listele si derivatele ei (stiva i coada) care sunt structuri de date liniare,arborii sunt structuri de date ierarhice. Arborii de obicei sunt utilizai n aa domenii ca SistemeOperaionale, Grafice, Baze de Date, Reea.

    Se numeste Arbore cu radacina = graf neorientat conex fara cicluri in care unul din noduri estedesemnat ca radacina. Nodurile pot fi asezate pe niveluri incepand cu radacina care este plasata penivelul 1.

    Rdcin - Nod special care genereaz aezarea unui arbore pe niveluri. Aceast operaie seefectueaz n funcie de lungimea lanurilor prin care celelalte noduri sunt legate de rdcin.

    Nod Element fundamental n arbore. El poate avea nume prin intermediul care l apelm. Elmai poate avea informaie adugtoare

    Arc Element la fel fundamental n arbore. Un arc poate lega 2 noduri pentru a arta o relaientre ele. Fiecare nod cu excepia rdcinei are doar un singur arc incident i poate aveam maimulte arce adiacente.

  • Descendent - ntr-un arbore cu rdcina nodul Y este descendentul nodului X daca este situat peun nivel mai mare dect nivelul lui X i exista un lan care le unete i nu trece prin rdcina.

    Descendent direct / fiu - ntr-un arbore cu rdcina nodul Y este fiul (descendentul direct)nodului X dac este situat pe nivelul imediat urmtor nivelului lui X i exist muchie ntre X iY.

    Drum O list ordonat de noduri legat prin noduri.

    Ascendent - ntr-un arbore cu rdcina nodul X este ascendentul nodului Y dac este situat peun nivel mai mic dect nivelul lui Y i exist un lan care le unete i nu trece prin rdcina.

    Ascendent direct / printe - ntr-un arbore cu rdcina nodul X este printele (ascendentuldirect) nodului Y dac este situat pe nivelul imediat superior (cu numar de ordine mai mic)nivelului lui Y i exista muchie ntre X i Y.

    Frai - ntr-un arbore cu rdcina nodul X este fratele nodului Y dac au acelai printe.

    Frunz - intr-un arbore cu rdcina nodul X este frunz dac nu are nici un descendent direct

    Cum un arbore este un caz particular de graf neorientat inseamna ca poate fi reprezentat ca un graf. Deaici rezulta ca pentru reprezentarea unui arbore se pot utiliza:

    Metode specifice grafurilor; Metode specifice arborilor

    ntr-o structur de tip arbore, elementele sunt structurate pe nivele: pe primul nivel, numit nivel 0,exist un singur element numit rdcin, de care sunt legate mai multe elemente numite fii careformeaz nivelul 1, de acestea sunt legate elementele de pe nivelul 2 . a. m. d.

    Propriet i a Arborilor Arborii sunt o structur ierarhic (adic pe niveluri) Toii fii unui nod sunt independei de fii altui nod Fiecare frunz a unui nod este unic

    O parte din sistemul opera ional UNIX

    root fiu1 frunz

  • Un exemplu unde am putea folosit structura arborescenta a structurilor de date cu folos ar fi un sistemade care ne folosim zilnic

    / rdcin / \

    ... Documente / \

    teza cursuri / / | \

    cs101 cs112 cs113

    Opera ii:Cutarea

    Operaia poate fi recursiv sau iterativ. Noi ncepem s analizm rdcina. Dac rdcina esteNULL, atunci nodul cutat nu exist n arbore. n caz c avem arbore binar de cutare i rdcina nueste NULL, atunci noi comparm valoarea nodului cutat cu rdcina. Dac valoarea e mai micatunci cutam pe subarborele stng, dac e mai mare atunci pe subarborele drept.function Find-recursive(key, node){ if (node == Null || node.key == key) return node else if (key < node.key) return Find-recursive(key, node.left) else return Find-recursive(key, node.right)}

    function Find-iterative(key, root){ current-node = root; while (!current-node){ if {current-node.key == key) return current-node; else if (key < current-node.key) current-node = current-node.left else current-node = current-node.right return Null;}

  • Inserarea

    Operaie este asemntoare cu cutarea binar. Noi cream nodul i cutam unde sa-l insermcomparnd valoarea introdus cu cele existente n noduri. La fel dac e mai mic atunci plecm pesubarborele stng i n caz contrar pe cel drept.fvoid insert(Node*& root, int data) { if (!root) root = new Node(data); else if (data < root->data) insert(root->left, data); else if (data > root->data) insert(root->right, data);}

    tergereaSunt 3 posibiliti de tergere:

    tergerea unui nod fr fii (pur i simplu tergem nodul) tergerea unui nod cu un fiu (tergem nodul i l nlocuim cu fiul lui) tergerea unui nod cu doi fii (preluam valoarea unui nod i tergem nodul preluat)

    void delete(struct node *root, int key){struct node *curent=malloc(sizeof(*curent));struct node *pred=malloc(sizeof(*precedent)); //ii globalacurent=root;while(curent->data!=key){/*In care parte sa mearga daca nu a fost gasita valoarea*/if (curent->data > key) delete(curent->left); else delete(curent>right);/*Cazul 1*/if (curent->left==NULL && curent->right==NULL) free(curent);/*Cazul 2 si cazul 3*/if (pred->data > curent->data){if (curent->left!=NULL && curent->right==NULL){pred->left=curent->left; free(curent);}if (curent->left==NULL && curent->right!=NULL){pred->left=curent->right; free(curent);}if (curent->left!=NULL && curent->right!=NULL) //cazul 3{pred->left=curent->left; curent=curent->left;curent->right=root->right;free(root);}}else {if (curent->left!=NULL && curent->right==NULL){pred->right=curent->left; free(curent);}if (curent->left==NULL && curent->right!=NULL){pred->right=curent->left; free(curent);}if (curent->left!=NULL && curent->>right!=NULL) //cazul 3{predd->right=curent->left;curent=curent->left;curent->right=root->right;free(root);}}}}

  • S creem primul arbore simplu cu 4 noduri. arbore ---- 1 rdcin / \ 2 3 / 4

    struct node { int data; struct node *left; struct node *right;};

    struct node* newNode(int data){ // Alocam memorie pentru noul nod struct node* node = (struct node*)malloc(sizeof(struct node));

    // atribuim infomatia nodului node->data = data;

    // Setam fiul drept si sting ca NULL node->left = NULL; node->right = NULL; return(node);}

    int main(){ /*cream radacina*/ struct node *root = newNode(1); /* arborele la momentul dat

    1 / \ NULL NULL */

    root->left = newNode(2); root->right = newNode(3); /* 2 si 3 devin valorile fiilor drept si sting 1 / \ 2 3 / \ / \

  • NULL NULL NULL NULL */

    root->left->left = newNode(4); /* 4 devine fiul sting al lui 2 1 / \ 2 3 / \ / \ 4 NULL NULL NULL / \NULL NULL*/ getchar(); return 0;}

    void stergere_arbore(TIP_NOD *rad) {

    if (rad !=0) //este asemanator cu if(rad!=NULL) { stergere_arbore (rad->stg); stergere_arbore (rad->dr);free (rad); }

    }

  • #include #include #include "conio.h"

    struct bst {int informatia;struct bst *dreapta, *stinga;

    };

    typedef struct bst nod;

    void insert(nod **arbore, int valoare){ nod *temp = NULL; if(!(*arbore)) { temp = (nod *)malloc(sizeof(nod)); temp->stinga = temp->dreapta = NULL; temp->informatia = valoare; *arbore = temp; return; }

    if(valoare < (*arbore)->informatia) insert(&(*arbore)->stinga, valoare); else if(valoare > (*arbore)->informatia) insert(&(*arbore)->dreapta, valoare);}

    void afiseaza_preordine(nod *arbore){ if (arbore) { printf("%3d",arbore->informatia); afiseaza_preordine(arbore->stinga); afiseaza_preordine(arbore->dreapta); }

    }

    void afiseaza_inordine(nod * copac){ if (copac) { afiseaza_inordine(copac->stinga); printf("%3d",copac->informatia); afiseaza_inordine(copac->dreapta); }}

  • void afiseaza_postordine(nod * copac){ if (copac) { afiseaza_postordine(copac->stinga); afiseaza_postordine(copac->dreapta); printf("%3d",copac->informatia); }}

    void delete_copac(nod * copac){ if (copac) { delete_copac(copac->stinga); delete_copac(copac->dreapta); free(copac); }}

    nod* search(nod ** copac, int valoare){ if(!(*copac))

    {return NULL;

    }

    if(valoare < (*copac)->informatia) search(&((*copac)->stinga), valoare); else if(valoare > (*copac)->informatia) search(&((*copac)->dreapta), valoare); else if(valoare == (*copac)->informatia) return *copac;}void main(){ nod *radacina; nod *tmp; int x;

    radacina = NULL; /* Inserarea nodurilor in arbore */ while(x!=0)

    { printf("valoarea >> ");scanf("%d",&x);clrscr();gotoxy(0,0);if (x==0) continue;insert(&radacina, x);}

  • /* Afisarea nodurilor din arbore */ textcolor(IYELLOW); printf("\nAfisare Preordine\n"); afiseaza_preordine(radacina);

    textcolor(IMAGENTA); printf("\n\nAfisare Inordine\n");

    afiseaza_inordine(radacina);textcolor(CYAN);

    printf("\n\nAfisare Postordine\n"); afiseaza_postordine(radacina); /* Cautarea unui nod concret */ numar:textcolor(CC_CLEAR); printf("\nCe nod vreti s-a caut stapine >> "); scanf("%d",&x); tmp = search(&radacina, x); if (tmp) { textcolor(IGREEN); printf("\nNodul cautat %d a fost gasit\n", tmp->informatia); } else { textcolor(IRED); printf("\nNu ma bate stapine dar nu este valoareorea in arbore\n"); goto numar; }textcolor(CC_CLEAR); /* Sterge toate nodurile din arbore */ delete_copac(radacina);}

    Descrierea scenariului:

    Programul pe care trebuie de realizat const n crearea unui program care va putea efectua toateoperaiile posibile cu arborii. Cu alte cuvinte el trebuie s fie capabil s ofere exemple, teorie,implementarea lor s.a.m.d.

    Concluzii:

    Pe parcursul acestei lucrri am respectat cu strictee obictivele i cerinele date de profesor. Amdescris principiile structurilor de date i importana acestora n elaborarea programelor. La fel amprezentat o scurt introducere in tipurile de reprezentare a structurilor de date n limbajul deprogramare C adugnd listingul funciilor pentru fiecare moment explicat, completat spre sfrit cu oorganigram.

    Fiind dat cerina de a elabora o aplicaie ce va reprezenta o bibliotec SDA care va lucra cuarborii i derivatele lui, am recapitulat nc odata arborii despre care am scris mai sus i am pornit aface un program care va stoca oferi detalii i exemple despre aceti arbori ct i exemple deimplementarea lor.

    Pe parcursul acestei lucrri am ntrit cunotinele n arbori la fel i reprezentarea lor n limbajulde programare C.

  • Literatura:

    http://geeksquiz.com/http://www.geeksforgeeks.org/data-structures/http://stackoverflow.com/

    Anexa.1 Listingul

    teza.c#include #include #include #include #include "conio.h"#include "search_delete_insert_node.c"#include "Adincime si Largime.c"#include "Costul minim pina la o destinatie.c"#include "lista_adiacenta_in graf.c"/* PROTATIPURI DE FUNCTII */void help();void arbore();void quit();void menu();

    /* PROGRAMUL PRINCIPAL */int main(){clrscr();gotoxy(0,0);/* LOGO */textcolor(ICYAN);puts("######## ######## ######## ### ");puts(" ## ## ## ## ## ");puts(" ## ## ## ## ## ");puts(" ## ###### ## ## ## ");puts(" ## ## ## ######### ");puts(" ## ## ## ## ## ");puts(" ## ######## ######## ## ##### ");puts(" ## ## ## ## ## ## ");puts(" ## ## ## ## ## ");puts(" ###### ## ## ## ## ");puts(" ## ## ## ######### ");puts(" ## ## ## ## ## ## ");puts(" ###### ######## ## ## ");puts("");/* MENU */textcolor(IGREEN);printf("[H]elp\nA[r]bore\n[C]autare-Inserare-Stergere\n[A]dincime si Largime (Graf)\n[M]inimum Cost\n[L]istaAdiacenta in Graf\n[Q]uit\n\n");char optiune;printf(" >> "); scanf("%c",&optiune);switch(optiune)

    {case 'h' : help(); break;case 'r' : arbore(); break;case 'c' : SDIN(); break;

  • case 'a' : AL(); break;case 'm' : MCG(); break;case 'l' : LAG(); break;case 'q' : quit(); break;

    }return 0;}void help(){

    clrscr();gotoxy(0,0);textcolor(CC_CLEAR);FILE *f;char c;f=fopen("help.txt","r");if (f==NULL) puts("WTF, fisierul e gol !!!");while (!feof(f)){

    fscanf(f,"%c",&c);printf("%c",c);

    }fclose(f);sleep(5); //asteapta 5 secunde - in Win se numara in ms in Unix in secgetchar();puts("Apasa ENTER pentru a te intoarce in Meniul principal");getchar();menu();

    }void arbore(){

    clrscr();gotoxy(0,0);textcolor(CC_CLEAR);FILE *f;char c;f=fopen("arbore.txt","r");if (f==NULL) puts("WTF, fisierul e gol !!!");while (!feof(f)){

    fscanf(f,"%c",&c);printf("%c",c);

    }fclose(f);sleep(3); //asteapta 3 secundegetchar();puts("Apasa ENTER pentru a te intoarce in Meniul principal");getchar();menu();

    }

    void quit(){textcolor(CC_CLEAR);puts("Iesire cu succes");sleep(1);}

    void menu(){clrscr();gotoxy(0,0);textcolor(IGREEN);printf("[H]elp\nA[r]bore\n[C]autare-Inserare-Stergere\n[A]dincime si Largime (Graf)\n[M]inimum Cost\n[L]istaAdiacenta in Graf\n[Q]uit\n\n");char optiune;

  • printf(" >> "); scanf("%c",&optiune);switch(optiune)

    {case 'h' : help(); break;case 'r' : arbore(); break;case 'c' : SDIN(); break;case 'a' : AL(); break;case 'm' : MCG(); break;case 'l' : LAG(); break;case 'q' : quit(); break;

    }textcolor(CC_CLEAR);}

    Costul minim pina la o destinatie.c

    // Valoarea infinita#define INF 999// Numarul de destinatii#define N 4//Functie recursiva pentru gasirea drumului scurt de la sursa S pina la destinatia Dint minCostRec(int cost[][N], int s, int d){ int i;// Daca sursa e aceeasi ca si destinatia or destinatia este urmatoarea dupa sursa if (s == d || s+1 == d) return cost[s][d];//Initializam constul minim ca link direct de la sursa S spre destinatia D int min = cost[s][d];// Incercam fiecare cale for (i = s+1; i

  • lista_adiacenta_in graf.c

    struct AdjListNode{ int dest; struct AdjListNode* next;};

    struct AdjList{ struct AdjListNode *head; };

    struct Graph{ int V; struct AdjList* array;};

    struct AdjListNode* newAdjListNode(int dest){ struct AdjListNode* newNode = (struct AdjListNode*) malloc(sizeof(struct AdjListNode)); newNode->dest = dest; newNode->next = NULL; return newNode;}

    struct Graph* createGraph(int V){ struct Graph* graph = (struct Graph*) malloc(sizeof(struct Graph)); graph->V = V;

    graph->array = (struct AdjList*) malloc(V * sizeof(struct AdjList));

    int i; for (i = 0; i < V; ++i) graph->array[i].head = NULL;

    return graph;}

    void addEdge(struct Graph* graph, int src, int dest){ struct AdjListNode* newNode = newAdjListNode(dest); newNode->next = graph->array[src].head; graph->array[src].head = newNode;

    newNode = newAdjListNode(src); newNode->next = graph->array[dest].head; graph->array[dest].head = newNode;}

    void printGraph(struct Graph* graph){ int v; for (v = 0; v < graph->V; ++v) {

  • struct AdjListNode* pCrawl = graph->array[v].head; textcolor(CYAN);getchar(); printf("\n Lista adiacenta pe ramura %d\n virf ", v); while (pCrawl) { printf("-> %d", pCrawl->dest); pCrawl = pCrawl->next; } printf("\n"); }}

    void LAG(){ int V = 5; struct Graph* graph = createGraph(V); addEdge(graph, 0, 1); addEdge(graph, 0, 4); addEdge(graph, 1, 2); addEdge(graph, 1, 3); addEdge(graph, 1, 4); addEdge(graph, 2, 3); addEdge(graph, 3, 4); printGraph(graph);getchar();menu();}

    Adincime si Largime.c

    // Afisarevoid dragos(){printf("Parcurgerea grafurilor in adincime si in largime\v\n");}void AL(){int i,j,k,l,n,s,x,y,h;char ch;

    // Introducerea virfurilordragos();L1:;int a[30][20],b[30];printf("Introduceti numarul de virfuri ale arborelui : ");scanf("%i",&n);printf("\n\t");printf("Introduceti lista de adiacenta :\n\n ");for(i=0;i

  • if(b[x]!=0) {b[0]=x+1; i++;}if(i>1) goto l2; // Eror!x=y=0;printf("\n\n\r");printf("PARCURGEREA IN LARGIME :\n\r");printf("\n x%d;",b[0]);for(i=1;i
  • search_delete_insert_node.c

    struct bst {int informatia;struct bst *dreapta, *stinga;};

    typedef struct bst nod;

    void insert(nod **arbore, int valoare){ nod *temp = NULL; if(!(*arbore)) { temp = (nod *)malloc(sizeof(nod)); temp->stinga = temp->dreapta = NULL; temp->informatia = valoare; *arbore = temp; return; }

    if(valoare < (*arbore)->informatia)insert(&(*arbore)->stinga, valoare);

    else if(valoare > (*arbore)->informatia)insert(&(*arbore)->dreapta, valoare);

    }

    void afiseaza_preordine(nod *arbore){ if (arbore) { printf("%3d",arbore->informatia); afiseaza_preordine(arbore->stinga); afiseaza_preordine(arbore->dreapta); }

    }

    void afiseaza_inordine(nod * copac){ if (copac) { afiseaza_inordine(copac->stinga); printf("%3d",copac->informatia); afiseaza_inordine(copac->dreapta); }}

    void afiseaza_postordine(nod * copac){ if (copac) { afiseaza_postordine(copac->stinga); afiseaza_postordine(copac->dreapta); printf("%3d",copac->informatia); }}

    void delete_copac(nod * copac){ if (copac)

  • { delete_copac(copac->stinga); delete_copac(copac->dreapta); free(copac); }}

    nod* search(nod ** copac, int valoare){ if(!(*copac))

    return NULL;

    if(valoare < (*copac)->informatia)search(&((*copac)->stinga), valoare);

    else if(valoare > (*copac)->informatia) search(&((*copac)->dreapta), valoare); else if(valoare == (*copac)->informatia) return *copac;}

    void SDIN(void){ nod *radacina; nod *tmp; int x=1;

    textcolor(CC_CLEAR); radacina = NULL; /* Inserarea nodurilor in arbore */ while(x!=0)

    { printf("valoarea [0 daca terminati] >> ");scanf("%d",&x);clrscr();gotoxy(0,0);if (x==0) continue;insert(&radacina, x);

    }

    /* Afisarea nodurilor din arbore */ textcolor(IYELLOW); printf("\nAfisare Preordine\n"); afiseaza_preordine(radacina);

    textcolor(IMAGENTA); printf("\n\nAfisare Inordine\n");

    afiseaza_inordine(radacina);

    textcolor(CYAN); printf("\n\nAfisare Postordine\n"); afiseaza_postordine(radacina);

    /* Cautarea unui nod concret */ numar:textcolor(CC_CLEAR); printf("\nCe nod vreti s-a caut stapine >> "); scanf("%d",&x); tmp = search(&radacina, x); if (tmp) { textcolor(IGREEN); printf("\nNodul cautat %d a fost gasit\n", tmp->informatia);

  • } else { textcolor(IRED); printf("\nNu ma bate stapine dar nu este valoareorea in arbore\n"); goto numar; }

    textcolor(CC_CLEAR);

    /* Sterge toate nodurile din arbore */ delete_copac(radacina); getchar(); menu();}

    Anexa.2 Rezultate: