Professional Documents
Culture Documents
Catedra Calculatoare
TEZ DE AN
la disciplina: Structuri de Date i Algoritmi
Bibliotec SDA
Determinarea arborilor de cutare
Chiinu 2015
Sarcina lucrrii:
Aplicaia Bibliotec SDA Determinarea arborilor de cutare n adncime i prin cuprindere. Grafuri
implementate prin grafuri adiacente, structuri de adiacente i toate variatele posibile.
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, n
continuare 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 Sisteme
Operaionale, Grafice, Baze de Date, Reea.
Se numeste Arbore cu radacina = graf neorientat conex fara cicluri in care unul din noduri este
desemnat ca radacina. Nodurile pot fi asezate pe niveluri incepand cu radacina care este plasata pe
nivelul 1.
Rdcin - Nod special care genereaz aezarea unui arbore pe niveluri. Aceast operaie se
efectueaz 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. El
mai poate avea informaie adugtoare
Arc Element la fel fundamental n arbore. Un arc poate lega 2 noduri pentru a arta o relaie
ntre ele. Fiecare nod cu excepia rdcinei are doar un singur arc incident i poate aveam mai
multe arce adiacente.
Descendent - ntr-un arbore cu rdcina nodul Y este descendentul nodului X daca este situat pe
un 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 i
Y.
Ascendent - ntr-un arbore cu rdcina nodul X este ascendentul nodului Y dac este situat pe
un 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 (ascendentul
direct) 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
fiu1
frunz
Cum un arbore este un caz particular de graf neorientat inseamna ca poate fi reprezentat ca un graf. De
aici 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 care
formeaz 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
Un exemplu unde am putea folosit structura arborescenta a structurilor de date cu folos ar fi un sistema
de 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 este
NULL, atunci nodul cutat nu exist n arbore. n caz c avem arbore binar de cutare i rdcina nu
este NULL, atunci noi comparm valoarea nodului cutat cu rdcina. Dac valoarea e mai mic
atunci 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 inserm
comparnd valoarea introdus cu cele existente n noduri. La fel dac e mai mic atunci plecm pe
subarborele 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);
}
tergerea
Sunt 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 globala
curent=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);}}}}
#include <stdlib.h>
#include <stdio.h>
#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);
}
}
Descrierea scenariului:
Programul pe care trebuie de realizat const n crearea unui program care va putea efectua toate
operaiile 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. Am
descris principiile structurilor de date i importana acestora n elaborarea programelor. La fel am
prezentat o scurt introducere in tipurile de reprezentare a structurilor de date n limbajul de
programare C adugnd listingul funciilor pentru fiecare moment explicat, completat spre sfrit cu o
organigram.
Fiind dat cerina de a elabora o aplicaie ce va reprezenta o bibliotec SDA care va lucra cu
arborii i derivatele lui, am recapitulat nc odata arborii despre care am scris mai sus i am pornit a
face un program care va stoca oferi detalii i exemple despre aceti arbori ct i exemple de
implementarea lor.
Pe parcursul acestei lucrri am ntrit cunotinele n arbori la fel i reprezentarea lor n limbajul
de programare C.
Literatura:
http://geeksquiz.com/
http://www.geeksforgeeks.org/data-structures/
http://stackoverflow.com/
Anexa.1 Listingul
teza.c
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#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
Adiacenta 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;
si
Largime
(Graf)\n[M]inimum
Cost\n[L]ista
si
Largime
(Graf)\n[M]inimum
Cost\n[L]ista
};
textcolor(CYAN);
getchar();
printf("Costul minim pentru a ajunge la statia %d este %d ",N, minCost(cost));
getchar();
menu();
}
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)
{
Adincime si Largime.c
// Afisare
void 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 virfurilor
dragos();
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<n;i++)
{ printf("\r%2i|",i+1);
scanf("%i",&a[i][0]);
for(j=1;j<n+1;j++)
if(a[i][j-1]!=0) scanf("%i",&a[i][j]);
else break;}
// Aici are loc parcurgerea in largime
for(i=0;i<n;i++) b[i]=i+1;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(a[i][j]!=0)
if(b[a[i][j]-1]!=0&&0<a[i][j]&&a[i][j]<=n) b[a[i][j]-1]=0;
else goto l2; // Eror!
else break;
for(i=0,x=0;x<n;x++)
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: