Capitolul IC.06. Arbori

Size: px
Start display at page:

Download "Capitolul IC.06. Arbori"

Transcription

1 Capitolul Cuvinte-cheie Arbori, reprezentări, inserare, căutare, parcurgere, ștergere, Echilibrare AVL, arbori binari optimali, arbori heap, sortare heap IC.06.1 Noţiuni generale Definiţie 1: Un arbore este o structură dinamică T ( C, R) de vârfuri (noduri) V şi R este o mulţime de muchii (arce) E. Deci T ( V, E) Structura T are proprietăţile: 1. nodul r V (nodul rădăcină), astfel încât,(, ) 2. x V \ r, y V unic, astfel încât ( yx, ) E = în care C este o mulţime x V x r E; au un predecesor şi numai unul); 3. x V, o secvenţă r = x0, x1, x2, K, xk = x, cu xi (proprietatea de conexiune); 4. x V xx, E(fără bucle)., ( ) = şi E V V. (toate nodurile diferite de rădăcină V şi ( x, x ) i i+ 1 Observaţie: Condiţia 4 este redundantă, dar a fost inclusă în definiţie din motive de claritate. T = V, E, este un arbore şi r V este rădăcina arborelui, Proprietate a arborelui: Dacă T, ( ) atunci mulţimea T \ r = ( Vʹ, Eʹ ), cu vʹ V \ r şi \ (, ) (, ) partiţionată astfel încât să avem mai mulţi arbori, a căror reuniune să fie T \ arbori intersectaţi să dea mulţimea vidă: 1 2 T r = T UT UL U T şi Ti I Tj i j. \ k Eʹ = E r x r x E, poate fi E r şi oricare doi Definiţia de mai sus a unui arbore, împreună cu proprietatea respectivă, având în vedere o structură dinamică şi recursivă, poate fi dată mai simplu astfel: Definiţie 2: Fiind dată o mulţime V de elemente numite noduri (vârfuri), arborele este un set finit de astfel de noduri, încât: 1. Există un nod, şi numai unul, care se numeşte rădăcina arborelui; 2. Celelalte noduri sunt repartizate în m 0 seturi disjuncte T1, T2, K, T, fiecare set T m i constituind la rândul său un arbore. Nodul rădăcină r formează nivelul 0 al arborelui. Deoarece T1, T2, K, T sunt la rândul lor m arbori, rădăcinile lor r 1, r 2, K, r m formează nivelul 1 al arborelui. Nodul r are câte o legătură (muchie) la nodurile r 1, r 2, K, r m. Continuând acest procedeu se ajunge la nivelurile 2,3, ale arborelui. r nivel 0 r 1 r 2 r m nivel 1 r 11 r 1k r m1 r mn nivel 2-1-

2 Un nod care nu are nici un nod subordonat se numeşte nod terminal sau nod frunză. În legătură cu arborii, s-a adoptat un limbaj conform căruia, un nod care are descendenţi direcţi se spune că este nod tată sau părinte. Nodurile descendente direct dintr-un nod tată (părinte) se numesc noduri fiu ale lui. De exemplu, în modelul de mai sus nodul r este 1 părinte pentru nodurile fiu r 11, K, r 1. Nodurile fiu ale aceluiaşi nod se numesc noduri frate. k Numărul de subarbori ai unui nod oarecare este gradul acelui arbore. Nodurile de grad zero sunt nodurile terminale (frunze). Nodurile de grad mai mare sau egal cu 1 sunt noduri interne sau neterminale. Gradul maxim al unuia din nodurile arborelui constituie și gradul unui arbore. Înălțimea unui arbore este dată de numărul de niveluri al acelui arbore. Definiție: Un arbore cu ordinul (gradul) mai mic sau egal cu 2 se numește arbore binar, iar unul cu gradul mai mare decât 2 se numește arbore multicăi. În cazul unui arbore binar se face distincția între cei doi fii ai unui nod, fiii acestui nod numindu-se fiul stâng și fiul drept. Este eficient în aplicații care implementează arbori să se lucreze cu arbori echilibrați. Echilibrarea unui arbore se poate face după următoarele criterii: - înălțime; - greutate; - pondere. De exemplu, echilibrarea după greutate se poate defini luând în calcul numărul de noduri. Definiție: Un arbore este echilibrat (după numărul de noduri) dacă pentru orice nod X T X și respectiv drept T ( X) ai lui X au un număr de noduri care al său subarborii stâng ( ) s diferă prin cel mult 1 ( ) ( adică card ( T X ) card ( T ( )) 1) s d X d. Definiție: Un arbore se numește complet dacă toate frunzele se află pe același nivel. Un arbore poate fi văzut și ca un tip abstract de date. Operațiile elementare caracteristice tipului arbore binar pot fi asupra nodurilor (creare, verificare, ștergere, etc.), asupra muchiilor sau asupra subarborilor. IC.06.2 Reprezentarea arborilor Toate metodele de reprezentare ale unui arbore încearcă să pună în evidență fiii sau părintele unui nod al arborelui. IC Reprezentarea standard În reprezentarea standard în fiecare nod al arborelui, pe lângă informația utilă se memorează informații de înlănțuire care indică descendenții. Într-o primă variantă de reprezentare, fiecare nod este compus din informația utilă și un vector de dimensiune fixă, în care se memorează legăturilor de tip pointer la descendenți. Dimensiunea acestui vector este dată gradul maxim al nodurilor arborelui. Declarațiile de tip folosite de această reprezentare sunt: struct Nod Atom data; Nod* vdesc[grmax]; ; -2-

3 Un nod va ocupa o zonă de memorie de dimensiune fixă: În figura de mai jos sunt reprezentate și înlănțuirile pentru arborele considerat: În această reprezentare, daca p este un pointer la un nod, descendentul i al nodului va fi identificat direct prin pointerul p->vdesc[i] Într-un arbore cu un număr N de noduri vor exista N-1 muchii, deci in total N-1 elemente din vectorii de pointeri la descendenți sunt ocupate cu informație utilă. Se obține raportul: N 1 1 = N * GRMAX GRMAX care indică gradul de utilizare eficientă a memoriei. În consecință aceasta reprezentare este acceptabilă numai pentru arbori de grad mic. IC Reprezentarea fiu-frate Pentru a obține o utilizare mai eficienta a memoriei, pot fi utilizate listele de descendenți. Fiecare nod va conține pe lângă informația utila, doi pointeri: unul va indica lista cu descendenții săi iar cel de-al doilea următorul nod din lista de descendenți din care face parte. -3-

4 Struct Nod Atom data; Nod* desc; Nod* next; ; În această variantă arborele de mai sus va avea următoarea reprezentare: Având in vedere semnificația pointerilor conținuți într-un nod, această reprezentare se mai numește reprezentarea fiu-frate. În aceasta reprezentare, dacă p este un pointer la un nod, identificarea descendentul i al nodului va necesita parcurgerea listei înlănțuite a descendenților, listă care începe cu: p->desc IC Reprezentarea prin noduri de dimensiune variabilă O a treia soluție de reprezentare combină economia de memorie cu avantajele accesării descendenților pe bază de index. Aceasta soluție se bazează pe posibilitatea de a aloca blocuri de memorie de lungime precizată. Vom considera aceeași declarație pentru tipul Nod ca și în prima variantă de reprezentare, adăugând în plus un câmp în care se memorează gradul nodului. struct Nod Atom data; int grad; Nod* vdesc[grmax]; ; Economia de memorie se va realiza prin alocarea unor zone de memorie de lungime variabilă, adaptată gradului fiecărui nod. Mai jos considerăm trei exemple de noduri de grad diferit: - nod de grad 3: -4-

5 - nod de grad 1: - nod terminal: Pentru a realiza economia de memorie este necesar ca la alocarea spațiului pentru un nod să se cunoască numărul de descendenți și în funcție de acest număr sa se aloce spațiul necesar pentru vectorul de descendenți. Functia make_nod care alocă spațiu pentru un nod de grad dat poate avea forma: Nod* make_nod(int grad) Nod *p=(nod*)malloc(sizeof(nod)-(grmax-grad)*sizeof(nod*)); p->grad = grad; return p; Utilizând operatorul new, specific limbajului C++, alocarea va avea forma: Nod* p = (Nod*) new char[sizeof(nod)-(grmax-grad)*sizeof(nod*)]; În această variantă, reprezentarea arborelui dat arată astfel: IC.06.3 Aplicație propusă: Evaluarea expresiilor aritmetice 1. Funcția Nod* crearearbore(); din Anexa citește de la intrare o expresie aritmetică, cu paranteze, care conține operanzi de o cifră și operatorii + si *, si crează arborele de grad oarecare asociat expresiei. De exemplu expresiei: -5-

6 1+2*3+4*(5+6) i se asociază arborele: Arborele este reprezentat după metoda 3, tipul Atom fiind echivalat cu tipul int (vezi Anexa). Se cere: - Să se determine și să se afișeze gradul arborelui. - Să se afișeze valoarea tuturor operanzilor utilizați în expresie (fără operatori). - Să se evalueze expresia și să se afișeze rezultatul. 2. Se dau două expresii care conțin numai operatorii + si *, operanzi specificați printr-o singură literă și paranteze rotunde. Să se determine dacă cele doua expresii sunt identice. Indicație: Se aduc cele două expresii la forma canonica (sumă de produse), se sortează termenii și se verifică dacă expresiile rezultate sunt egale. Expresia adusă la forma canonică va fi reprezentata sub forma unui arbore cu trei nivele, în care: - rădăcina este un nod Σ - semnificând un nod în care se face însumarea tuturor descendenților; - pe nivelul 2 vor fi noduri π - semnificând noduri in care se face produsul tuturor descendenților; - pe nivelul 3 vor fi operanzi. Vom numi astfel de arbori "arbori Σ(π)". De exemplu: Pentru a crea arborele Σ(π) corespunzător formei canonice se prelucrează arborele inițial executând următoarele operații: [A] - în nodurile terminale: a --> Σ π -6-

7 a [B] - in nodurile + : + --> Σ(π) / \ Σ1(π) Σ2(π) Nodul Σ va avea ca descendenți atât descendenții lui Σ1 cât și ai lui Σ2 (listele de descendenți vor fi concatenate). [C] - nodurile * : * --> Σ(π) / \ Σ1(π) Σ2(π) În acest caz arborele Σ(π) va conține un număr de descendenți egal cu produsul dintre numărul de descendenți ai nodului Σ1 și numărul de descendenți ai nodului Σ2, obținuți prin combinarea (înmulțirea) fiecare cu fiecare. Anexa Fisierul Arbore.h #ifndef _ARBORE_H_ #define _ARBORE_H_ #define DIM_EXPR 100 #define GRMAX 20 #define Atom int struct Nod Atom data; int grad; Nod* vdesc[grmax]; ; Nod* crearearbore(); #endif Fisierul Arbore.cpp #include "arbore.h" #include <string.h> #include <ctype.h> #include <stdlib.h> #include <conio.h> #include <stdio.h> #include <iostream.h> Nod* parse(char buffer[], int start, int end); Nod* crearearbore() -7-

8 char buffer[dim_expr]; cin >> buffer; int length = strlen(buffer); Nod* n = parse(buffer, 0, length-1); return n; Nod* parse(char buffer[], int start, int end) int openp = 0; int indici[grmax]; int k = 0; openp = 0; for (int i = start; i <= end; i++) if ( buffer[i]=='(' ) openp ++; if ( buffer[i]==')' ) openp --; if ( buffer[i]=='+' ) if ( openp > 0) continue; indici[k++] = i; if ( k > 0 ) Nod *p=(nod*) new char[sizeof(nod)-(grmax-k+1)*sizeof(nod*)]; p->grad = k+1; p->data='+'; p->vdesc[0] = parse(buffer, start, indici[0]-1); for (int j = 1; j < p->grad - 1; j++) p->vdesc[j] = parse(buffer, indici[j-1]+1, indici[j]-1); p->vdesc[p->grad-1] = parse(buffer, indici[p->grad-2]+1, end); return p; openp = 0; for (i = start; i <= end; i++) if ( buffer[i]=='(' ) openp ++; if ( buffer[i]==')' ) openp --; if ( buffer[i]=='*' ) if ( openp > 0) continue; indici[k++] = i; if ( k > 0 ) Nod *p=(nod*) new char[sizeof(nod)-(grmax-k+1)*sizeof(nod*)]; -8-

9 p->grad = k+1; p->data='*'; p->vdesc[0] = parse(buffer, start, indici[0]-1); for (int j = 1; j < p->grad - 1; j++) p->vdesc[j] = parse(buffer, indici[j-1]+1, indici[j]-1); p->vdesc[p->grad-1] = parse(buffer, indici[p->grad-2]+1, end); return p; if ( buffer[start] == '(' && buffer[end] == ')' ) return parse(buffer, start+1, end-1); if ( start==end ) if ( isdigit(buffer[start]) ) Nod* p = (Nod*) new char[sizeof(nod)-(grmax)*sizeof(nod*)]; p->data = buffer[start]; p->grad = 0; return p; printf("\nexpresia de intrare este eronata. Apasati o tasta"); getch(); exit(1); IC.06.4 Arbori binari IC Reprezentarea standard În reprezentarea standard, un nod al arborelui este o structură cu un câmp conținând eticheta nodului (data) și doua câmpuri pointeri la cei doi descendenți (lchild si rchild): Astfel, arborele: struct Nod type data; Nod* stg, *drt; ; va avea următoarea reprezentare: -9-

10 Pentru a putea prelucra un arbore este suficient să cunoaștem un pointer la nodul rădăcină. Valoarea nil pentru acest pointer va semnifica un arbore vid. IC Parcurgerea arborilor binari Un arbore binar poate fi privit conform următoarei scheme recursive: rad = rădăcină SAS = SubArbore Stâng SAD = SubArbore Drept Pentru această schemă se definesc cele trei moduri de parcurgere a arborelui: - preordine: rad SAS SAD sau mai simplu RSD (Rădăcină Stânga Dreapta) Se prelucrează mai întâi rădăcina apoi se parcurg în preordine subarborii stâng și drept. - inordine: SAS rad SAD sau SRD (Stânga Rădăcină Dreapta) Se parcurge în inordine subarborele stâng, se prelucrează rădăcina și apoi se parcurge în inordine subarborele drept. - postordine: SAS SAD rad sau SDR (Stânga Dreapta Rădăcină) Se parcurg mai întâi în postordine subarborii stâng și drept apoi se prelucrează rădăcina. De exemplu, pentru arborele: cele trei parcurgeri prelucrează nodurile în ordinea: preordine: inordine: postordine: A B D C E F B D A E C F D B E F C A -10-

11 Se pot realiza aceste parcurgeri utilizând subrutine recursive. De exemplu, pentru parcurgerea în preordine avem: sau void PREORDINE(pNod p); if (p!=null) prelucreaza(*p); PREORDINE(p->lchild); PREORDINE(p->rchild); void PREORDINE(Nod* p); prelucreaza(*p); if(p->stg!=null) PREORDINE(p->stg); if(p->drt!=null) PREORDINE(p->drt); A doua varianta nu poate fi aplicata unui arbore vid, în timp ce prima tratează corect arborele vid, în schimb execută un apel recursiv în plus pentru fiecare legătură care este NULL. Alte modalităţi de parcurgere ale unui arbore sunt parcurgerea în lăţime sau în adâncime. IC Aplicație În cele ce urmează prezentăm o aplicație care efectueze următoarele: 1. afișează conținutul arborelui în inordine; 2. afișează conținutul arborelui în postordine; 3. determină adâncimea arborelui; 4. determină numărul de noduri din arbore; 5. determină numărul de frunze ale arborelui; 6. determină valoarea maximă și valoarea minimă din arbore; 7. afișează nodurile care au valoarea din rădăcina mai mare decât toate valorile din subarborii descendenți; 8. afișează toate nodurile pentru care toate valorile conținute in subarborele stâng sunt mai mici decât toate valorile conținute în subarborele drept; 9. pentru fiecare nod să se comute subarborele stâng cu cel drept. În modulul ARBORE.CPP (vezi Anexa) sunt specificate declarațiile tipurilor: și funcția: struct Nod char data; struct Nod *stg, *drt; Nod* crearearbore(); -11-

12 care citește un arbore specificat conform următoarei diagrame de sintaxă, și întoarce pointer la rădăcina arborelui citit. În diagrama: '-' - semnifică un arbore vid; nume - este eticheta unui nod formata dintr-o literă. Exemple: arbore vid: - Anexa Arbore.h struct Nod char data; Nod* stg, *drt; ; Nod* crearearbore(); Arbore.cpp #include <alloc.h> #include <conio.h> #include <stdlib.h> #include <stdio.h> #include <ctype.h> -12-

13 #include "arbore.h" void eroare(); char readchar(); char citestenume(); Nod* citestearbore(); Nod* crearearbore(); char car; void eroare() printf("sirul de intrare este eronat!\n"); printf("apasati tasta o tasta..."); getch(); exit(1); char readchar() char c; do c=getchar(); while(c==' '); return c; char citestenume() char c; if(!isalpha(car)) eroare(); c = car; car = readchar(); return c; Nod* citestearbore() Nod* rad; if( car=='-' ) rad=0; car = readchar(); rad = (Nod*) malloc(sizeof(nod)); rad->data = citestenume(); if( car!='(' ) rad->stg = 0; rad->drt = 0; car = readchar(); rad->stg = citestearbore(); if( car!=',' ) rad->drt = 0; car = readchar(); rad->drt = citestearbore(); if( car!=')' ) eroare(); car = readchar(); return rad; -13-

14 Nod* crearearbore() printf("\nintroduceti arborele:"); car = readchar(); return citestearbore(); Funcțiile care realizează cerințele specificate sunt date mai jos, în modulul FUNCTII.CPP. Afișarea este realizată în variantele recursivă și nerecursivă. Pentru varianta nerecursivă este utilizată o stivă, din acest motiv am specificat și funcțiile pentru stiva respectivă în modulul STACK.CPP FUNCTII.CPP #include <stdio.h> #include <string.h> #include arbore.h #include stack.cpp void AfisInordine(Nod* nod) if(nod==0) return; AfisInordine(nod->stg); printf( %c,nod->data); AfisInordine(nod->drt); void AfisPostordine(Nod* nod) if(nod==0) return; AfisPostordine(nod->stg); AfisPostordine(nod->drt); printf( %c,nod->data); int Adancime(Nod* nod) if(nod==0) return 0; int maxs=1, maxd=1; maxs = 1 + Adancime(nod->stg); maxd = 1 + Adancime(nod->drt); if(maxs < maxd) return maxd; return maxs; int Noduri(Nod* nod) -14-

15 if(nod==0) return 0; return 1 + Noduri(nod->stg) + Noduri(nod->drt); int Frunze(Nod* nod) if(nod==0) return 0; if((nod->stg==0) && (nod->drt==0)) return 1; return Frunze(nod->stg) + Frunze(nod->drt); void Rad_sup(Nod* nod) //nod ce are valoarea mai mare decat val. Din //subarbori if(nod==0) return; if(nod->data==max(nod)) printf( %c,nod->data); Rad_sup(nod->stg); Rad_sup(nod->drt); char max(nod* nod) //val maxima dintr-un arbore if(nod==0) return 0; char maxim; maxim=nod->data; if(maxim < max(nod->stg)) maxim=max(nod->stg); if(maxim < max(nod->drt)) maxim=max(nod->drt); return maxim; char min(nod* nod) //val minima dintr-un arbore if(nod==0) return 0; char minim; minim=nod->data; if(minim > min(nod->stg)) minim=min(nod->stg); if(minim > min(nod->drt)) minim=min(nod->drt); return minim; void Stg_inf(Nod* nod) //maxim subarbore stang<minim subarbore drept if(nod==0) return; if((nod->stg==0) && (nod->drt==0)) return; -15-

16 if(min(nod->drt) > max(nod->stg)) printf( %c,nod->data); Stg_inf(nod->stg); Stg_inf(nod->drt); void Comuta(Nod *&r) Nod *aux; if(r==0) return; aux=r->drt; r->drt=r->stg; r->stg=aux; Comuta(r->drt); Comuta(r->stg); void AfisInordine_nrec(Nod* p) Stack s; initstack(s); while(1) while(p!=0) push(s,p); p=p->stg; if(isempty(s)) break; p=pop(s); printf( %c, p->data); p=p->drt; void AfisPreordine_nrec(Nod* p) Stack s; initstack(s); while(1) while(p!=0) printf( %c, p->data); push(s,p); p=p->stg; if(isempty(s)) break; p=pop(s); p=p->drt; //afisare inordine nerecursiva //afisare preordine nerecursiva -16-

17 STACK.CPP #include <stdio.h> typedef Nod* Atom; struct Element Atom data; Element* next; ; typedef Element* Stack; void initstack(stack& S) S=0; int isempty(stack& S) return(s==0); void push(stack& S, Atom val) Element *p; p=new Element; p->data=val; p->next=s; S=p; Atom pop(stack& S) Atom aux; Element *p; p=s; if(isempty(s)==1) //printf("eroare!stiva vida!nu putem extrage!"); return 0; aux=p->data; S=S->next; delete p; return aux; Atom top(stack& S) if(isempty(s)==1) //printf("eroare!stiva vida!nu are varf!"); return 0; return S->data; -17-

18 IC.06.5 IC Arbori binari de căutare (BST) Noțiuni generale Definiție: Un arbore binar de căutare (BST) este un arbore binar cu următoarele proprietăți: 10. fiecare nod conține un câmp cheie astfel încât pe mulțimea constantelor tipului cheii să existe o relație de ordine; 11. oricare ar fi un nod x al arborelui, dacă y Ts ( x) (subarborele stâng) atunci cheie(y)<cheie(x) și dacă y Td ( x) (subarborele drept) atunci cheie(y)>cheie(x). De obicei cheile stocate în nodurile unui arbore sunt considerate distincte. O proprietate a unui arbore BST constă în faptul că parcurgerea în inordine (SRD) sortează crescător elementele mulţimii cheilor. Arborii binari de căutare implementează eficient următoarele operaţii: 12. search(arbore, k) - determină dacă un element specificat prin cheia de sortare k, există în arbore şi-l returnează dacă există; 13. insert(arbore, x) - inserează în arbore elementul x; 14. delete(arbore, k) - şterge un element specificat, specificat prin cheia k. Proprietatea care defineşte structura unui arbore binar de căutare este următoarea: valoarea cheii memorate în rădăcina este mai mare decât toate valorile cheilor conţinute în subarborele stâng şi mai mică decât toate valorile cheilor conţinute în subarborele drept. Această proprietate trebuie să fie îndeplinita pentru toţi subarborii, de pe orice nivel, în arborele binar de căutare. Exemplu (pentru fiecare nod s-au reprezentat numai cheile de căutare): IC Operaţii caracteristice Inserarea şi căutarea unui nod într-un arbore binar de căutare a) varianta recursivă: Funcţia insert poate avea următoarea formă: insert(r,a) // r - pointer la radacina (trasmis prin referinta) // a - atomul de inserat if r=0 then r = make_nod(a) if key(a) < key(data(r)) then insert(lchild(r),a) if key(a) > key(data(r)) then -18-

19 insert(rchild(r),a) unde funcţia care creează nodul este: make_nod(a) // creeaza un nod nou in care memoreaza atomul a p = get_sp() // aloca spatiu pentru un nod data(p) = a lchild(p) = rchild(p) = 0 return (p) Pentru varianta de mai sus trebuie ca funcţia insert să modifice valoarea argumentului r, pentru aceasta el va fi un parametru transmis prin referinţă. În implementarea C++ funcţia insert poate avea prototipul: void insert(nod*& r, Atom a); O variantă care nu necesita argument referinţă (deci poate fi implementata în C) este dată mai jos. insert(r,a) if r=0 then return ( make_nod(a) ) if key(a) < key(data(r)) then lchild(r) = insert(lchild(r),a) if key(a) > key(data(r)) then rchild(r) = insert(rchild(r),a) return (r) Apelul acestei variante va avea de fiecare data forma: rad = insert(rad, a) Procedura search întoarce un pointer la nodul cu cheia de căutare dată sau pointerul NULL dacă nu există nodul respectiv. search(r,k) if ( r=0 ) return NULL if k < key(data(r)) then return ( search(lchild(r),k) ) if k > key(data(r)) then return ( search(rchild(r),k) ) return (r) b) varianta nerecursivă Trebuie observat că atât operaţia search cât şi operaţia insert parcurg o ramură a arborelui (un lanţ de la rădăcina spre o frunză). Această parcurgere poate fi efectuata iterativ. Este vorba de a parcurge o înlănţuire, deci se impune o analogie cu parcurgerea listei înlănţuite. -19-

20 Parcurgerea listei înlănţuite Parcurgerea unei ramuri in arbore p=cap; p=rad; while(p!=0) while(p!=0) Prelucrare element Prelucrea nod p = p->link; if(conditie) p=p->stg p=p->drt; Procedura de inserare într-un arbore binar de căutare, realizată nerecursiv, are următoarea formă (presupunem că r este parametru transmis prin referinţă): insert(r,a) if ( r=0 ) r = make_nod(a) p = r while ( p<>0 ) p1 = p if key(a)<key(data(p)) then p=lchild(p) if key(a)>key(data(p)) then p=rchild(p) return if ( key(a)<key(data(p1)) ) lchild(p1) = make_nod(a) rchild(p1) = make_nod(a) Ştergerea unui nod dintr-un arbore binar de cautare În continuare se prezintă o funcţie C++ pentru ştergerea unei valori dintr-un arbore binar de căutare care conţine numere întregi. Pentru ştergerea unei valori din arbore este necesara mai întâi identificarea nodului care conţine această valoare. În acest scop folosim tehnica prezentata la operaţia search. Pentru simplitate consideram nodurile etichetate cu numere întregi care vor constitui chiar cheile de căutare (key(data(p) = data(p)). struct Nod int data; Nod* stg, *drt; ; void delete(nod*& rad, int a) if(rad==null) printf("eroare: Valoarea %d nu este in arbore!", a); if( a<rad->data ) delete(rad->stg,a) if( a>rad->data ) delete(rad->drt,a) deleteroot(rad); S-a redus sarcina iniţială la a scrie funcţia deleteroot care şterge rădăcina unui arbore binar de căutare nevid. Trebuie tratate următoarele cazuri: -20-

21 1. rădăcina nu are nici un descendent şi ştergerea este o operaţie imediată. 2. rădăcina are un sigur descendent şi nodul şters va fi înlocuit cu subarborele descendent. 3. rădăcina are doi descendenţi şi ea va fi înlocuită cu nodul cu valoarea cea mai mare din subarborele stâng, acest nod având întotdeauna cel mult un descendent. Nodul cel mai mare dintr-un arbore (subarbore) binar de căutare se găseşte pornind din rădăcina şi înaintând cât se poate spre dreapta. De exemplu Deci: -21-

22 Următoarea funcţie detaşează dintr-un arbore binar de căutare nevid nodul cu valoarea cea mai mare şi întoarce un pointer la acest nod. Nod* removegreatest(nod*& r) Nod* p; if( r->drt==0 ) p = r; r = r->stg; return p; return removegreatest(r->rchild); Varianta prezentată este recursiva. Se poate scrie uşor şi o variantă nerecursivă pentru această procedură. Ţinând cont de cazurile posibile prezentate, procedura deleteroot va trata separat cazurile: - daca subarborele stâng este vid: promovează subarborele drept. Cazul in care si subarborele drept este vid nu trebuie tratat separat, in acest caz se promovează arborele vid (rad devine NULL); - altfel daca, subarborele drept este vid: promovează subarborele stâng. - altfel (ambii subarbori nu sunt vizi): înlocuieşte rădăcina cu cel mai mare nod din subarborele sting. void deleteroot(nod*& rad) Nod* p = rad; if( rad->stg==0) rad = rad->drt; if( rad->drt==0) rad = rad->stg; rad = removegreatest (rad->stg); -22-

23 rad->stg = p->stg; rad->drt = p->drt; delete p; Temă 1. Se citeşte de la intrare un şir de valori numerice întregi, pe o linie, separate de spaţii, şir care se încheie cu o valoare 0. a) Să se introducă valorile citite intr-un arbore binar de căutare (exclusiv valoarea 0 care încheie şirul). b) Să se afişeze în inordine conţinutul arborelui. c) Se citeşte o valoare pentru care sa se verifice dacă este sau nu conţinută în arbore. d) Se citeşte o valoare care să fie ştearsă din arbore şi apoi să se afişeze arborele în inordine. e) Să se determine succesorul şi predecesorul unui nod. f) Să se afişeze conţinutul arborelui parcurgându-l în lăţime. Să se construiască un program C/C++ care, cu ajutorul unui meniu simplu, să permită efectuarea operaţiilor definite mai sus. 2. Să se construiască modul C/C++ care să conţină tipurile de date şi operaţiile care implementează sub forma unui arbore binar de căutare o agenda de numere de telefon. Un nod al arborelui va conţine: - numele persoanei (cheie de căutare); - numărul de telefon; Să se definească procedurile care: - inserează un element în agendă; - şterge din agendă o persoana dată; - caută în agenda numărul de telefon al unei persoane date; - afişează agenda în întregime. Să se construiască un program C/C++ care cu ajutorul unui meniu simplu să permită selectarea operaţiilor definite mai sus. Pentru problema 1 se pot folosi şi funcţiile date în modulele de mai jos (ARBORE.H, FUNCTII.CPP, COADAGEN.H). Primul modul conţine structura unui nod şi prototipurile funcţiilor. Deoarece pentru parcurgerea în lăţime s-a utilizat o coadă generică este dat şi modulul respectiv. Suplimentar se prezintă şi o funcţie pentru afişarea indentată a unui arbore. ARBORE.H #ifndef ARBORE_H #define ARBORE_H typedef int Tip_cheie; struct Nod Tip_cheie cheie; void *info; Nod *fst, *fdr; //cheia este chiar valoarea //pointer la informatia utila -23-

24 ; Nod *SearchR(Nod *r, Tip_cheie k); Nod* Search(Nod *r, Tip_cheie k); Nod *SearchMin(Nod *r); Nod *SearchMax(Nod *r); Nod* MakeNod(Tip_cheie k); void Insert(Nod *&r, Tip_cheie k); void InsertN(Nod *&r, Tip_cheie k); void AfisNod(Nod *r, int nivel); void AfisArbore(Nod *r); Nod *crearearbore(); void inorder(nod *r); void DelNod(Nod *&r, Tip_cheie k); void ParcurgereLatime(Nod *r); Nod* Parinte(Nod *rad, Nod *r); Nod* SuccesorNod(Nod *rad, Tip_cheie k); Nod* PredecesorNod(Nod *rad, Tip_cheie k); #endif; FUNCTII.CPP #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <stdlib.h> #include <time.h> #include "arbore.h" #include "coadagen.h" // functia Search intoarce pointerul la nodul de cheie k // sau pointerul NULL daca nu exista nodul respectiv // varianta recursiva Nod *SearchR(Nod *r, Tip_cheie k) if(r==0 k==r->cheie) return r; if (k<r->cheie) return SearchR(r->fst,k); return SearchR(r->fdr,k); //varianta nerecursiva Nod* Search(Nod *r, Tip_cheie k) while (r!=0 && k!=r->cheie) if(k < r->cheie) r=r->fst; r=r->fdr; return r; // SerchMin - intoarce referinta (pointerul) la nodul cu cheia minima Nod *SearchMin(Nod *r) while (r->fst!= 0) r=r->fst; return r; // SearchMax - intoarce referinta (pointerul) la nodul cu cheia maxima Nod *SearchMax(Nod *r) -24-

25 while (r->fdr!= 0) r=r->fdr; return r; //MakeNod creaza un nod si intoarce pointerul la nodul creat Nod* MakeNod(Tip_cheie k) Nod *p; if((p=new Nod)==0) printf("makenod -eroare"); exit(1); p->cheie=k; p->fst=p->fdr=0; return p; //Insert - insereaza un nod de cheie data intr-un arbore BST //varianta recursiva void Insert(Nod *&r, Tip_cheie k) if(r==0) r=makenod(k); if (r->cheie > k) Insert(r->fst,k); if(r->cheie <k) Insert(r->fdr,k); printf("nod existent\n"); //daca cheile coincid nu se face inserarea //Varinata nerecursiva void InsertN(Nod *&r, Tip_cheie k) if(r==0) r=makenod(k); Nod *p, *p1; p=r; while(p!=0) p1=p; if(p->cheie > k) p=p->fst; if(p->cheie < k) p=p->fdr; //nodul exista printf("nodul exista\n"); return; // se iese cu p=0 si p1 indica nodul dupa care se insereaza if(k < p1->cheie) p1->fst=makenod(k); p1->fdr=makenod(k); //AfisNod - afiseaza arborele indentat void AfisNod(Nod *r, int nivel) int i; for(i=0; i<nivel; i++) printf("\t"); if(r==0) printf("-\n"); //se tipareste "-" pentru ceva vid printf("%d\n", r->cheie); AfisNod(r->fst, nivel+1); AfisNod(r->fdr, nivel+1); -25-

26 void AfisArbore(Nod *r) AfisNod(r,1); Nod *crearearbore() Nod *r; Tip_cheie k; r=0; printf("introduceti arborele (cheia coincide cu data), 0 - exit\n"); do printf("cheie: "); scanf("%d",&k); if (k==0) break; InsertN(r,k); while (1); return r; void inorder(nod *r) if(r!=0) inorder(r->fst); printf("%d ", r->cheie); inorder(r->fdr); //DelNod - sterge nodul cu cheia k dintr-un arbore BST void DelNod(Nod *&r, Tip_cheie k) if(r==0) return; //arbore vid sau nod inexistent if(r->cheie > k) DelNod(r->fst,k); if(r->cheie < k) DelNod(r->fdr,k); //s-a gasit nodul cu cheia k Nod *p; if(r->fst==0) //nodul are un singur fiu: fiul drept p=r; r=r->fdr; delete p; if(r->fdr==0) //nodul are un singur fiu: fiul stang; p=r; r=r->fst; delete p; // nodul are doi fii int i; i=2*rand()/rand_max; if (i!=0) p=searchmin(r->fdr); //cauta nodul de cheie minima //din subarborele drept r->cheie = p->cheie; DelNod(r->fdr, p->cheie);//sterge nodul respectiv -26-

27 p=searchmax(r->fst);//caut nodul de cheie maxima //din subarborele stang r->cheie=p->cheie; DelNod(r->fst, p->cheie);//sterge nodul respectiv //ParcurgereLatime void ParcurgereLatime(Nod *r) if(r==0) return; Queue Q; InitQ(Q); Put(Q,(void*)r); Nod *p; while(!isemptyq(q)) p = (Nod*)Get(Q); printf(" %d ", p->cheie); if(p->fst!= 0) Put(Q,(void*)p->fst); if(p->fdr!= 0) Put(Q,(void*)p->fdr); //Parinte(rad, p) determina parintele nodului p din arborele cu radacina //rad //intoarce pointerul la parinte Nod* Parinte(Nod *rad, Nod *r) if(r==rad) return 0; //radacina n-are parinte Nod *p, *q; p=q=rad; while(q!= r) p=q; if(q->cheie < r->cheie) q=q->fdr; q=q->fst; return p; //SuccesorNod() - determina pointerul la succesorul unui nod de cheie k Nod* SuccesorNod(Nod *rad, Tip_cheie k) Nod *r; r=search(rad,k); if(r==0) return 0; if(r->fdr!=0)//daca exista fiu drept, succesorul este minimul din SAD return SearchMin(r->fdr); Nod*p; p=parinte(rad, r); while(p!=0 && r==p->fdr)//cat timp exista parinte si r este fiu drept //urc in arbore pana cand r va fi intr-un r=p; //subarbore stang al unui nod p=parinte(rad, p); -27-

28 return p; //PredecesorNod() - determina pointerul la predecesorul unui nod de cheie k Nod* PredecesorNod(Nod *rad, Tip_cheie k) Nod *r; r=search(rad,k); if(r==0) return 0; if(r->fst!=0)//daca exista fiu stang, predec. este maximul din SAS return SearchMax(r->fst); Nod*p; p=parinte(rad, r); while(p!=0 && r==p->fst)//cat timp exista parinte si r este fiu stang //urc in arbore pana cand r va fi intr-un r=p; //subarbore drept al unui nod return p; COADAGEN.H #include <malloc.h> #include <stdio.h> #include <stdlib.h> #include <conio.h> typedef struct El void *info; struct El *succ; ELEMENT; p=parinte(rad, p); struct Queue ELEMENT *head, *tail; ; //pointeri la primul si ultimul element void InitQ(Queue &q) q.head = q.tail = 0; int IsEmptyQ(Queue q) return (q.head == 0 && q.tail== 0); void* Front(Queue q) if(isemptyq(q)) printf("front -- coada vida\n"); exit(1); return q.head->info; void* Get(Queue &q) void *temp; if(isemptyq(q)) printf("get -- coada vida\n"); exit(1); temp = q.head->info; -28-

29 if(q.head==q.tail) q.head = q.tail = 0; return temp; ELEMENT *p; p=q.head; q.head=p->succ; free(p); return temp; void Put(Queue &q, void *x) ELEMENT *p; if((p=(element*)malloc(sizeof(element)))==0) printf("put -- eroare alocare"); exit(1); p->info=x; p->succ=null; if(isemptyq(q)) q.head=q.tail=p; q.tail->succ=p; q.tail=p; IC.06.6 IC Arbori binari de căutare AVL echilibraţi Introducere Un arbore binar de căutare este AVL echilibrat dacă pentru fiecare nod, diferența dintre adâncimea subarborelui stâng şi cea a subarborelui drept este cel mult 1. Numele AVL provine de la iniţialele numelor celor ce l-au descoperit: Adelsohn-Velskii şi Landis. Deci arborii AVL sunt arbori echilibraţi după înălţime (reamintim că există şi echilibrări după greutate sau ponderi). S-a demonstrat că adâncimea (înălţimea) h a unui arbore AVL echilibrat cu n noduri satisface relaţia: log ( n+ 1) h log ( n+ 2) Optimul este atins pentru arborii total echilibraţi. Din relaţia anterioară rezultă că parcurgerea unei ramuri într-un arbore binar de căutare echilibrat AVL se va face in O(log n) paşi. Factorul de echilibru bf (balance factor) este definit prin diferenţa dintre adâncimea (înălţimea) subarborelui stâng şi adâncimea (înălţimea) subarborelui drept: ( ) ( ) bf = h T h T s d -29-

30 şi poate avea valorile: 1, 0, + 1. Operaţia de căutare într-un arbore binar de căutare care are şi proprietatea de a fi echilibrat este o operaţie de complexitate O(log n). Se pune problema construirii operaţiilor insert şi delete astfel încât ele să conserve proprietatea de arbore binar echilibrat dar, în acelaşi timp, să fie la rândul lor operaţii O(log n). Pentru a realiza acest lucru se memorează în structura unui nod şi factorul de echilibru (uneori se foloseşte şi terminologia factor de dezechilibru ). IC Metode de echilibrare La inserare sau ștergere, arborele trebuie reorganizat modificându-i-se structura, bf > 1 (care deja este numai atunci când inserarea sau ștergerea dezechilibrează un nod ( ) dezechilibrat în acelaşi sens). Operaţiile prin care este realizată echilibrarea sunt denumite rotaţii și sunt descrise mai jos. În următoarele figuri s-a reprezentat: - un nod al arborelui - un subarbore de adâncime h - un subarbore de adâncime h-1 Rotațiile se aplică arborilor (subarborilor) care, în urma inserării sau ștergerii, au nodul rădăcină dezechilibrat, dar toți subarborii sunt echilibrați. La inserarea unui nod X intr-un arbore, sunt patru cazuri posibile care necesită efectuarea unei rotații: -30-

31 și Rotații simple a) Rotație simplă dreapta Starea inițială Starea finală Subarborii T1, T2 și T3 au inițial aceeași adâncime h, iar nodul A are factorul de dezechilibru -1. Prin inserarea unui nod în subarborele T1 se mărește adâncimea acestuia și nodul A devine dezechilibrat. Prin operația numita rotație simplă dreapta se obține un arbore care respecta inegalitatea valabila pentru starea inițială: T1 < B < T2 < A < T3 ceea ce înseamnă că toate nodurile din subarborele T1 sunt etichetate cu valori mai mici decât eticheta (cheia) lui B, B este mai mic decât etichetele tuturor nodurilor din subarborele T2, etc. Arborele rezultat în urma rotației este echilibrat și are aceeași adâncime cu arborele inițial, adică are adâncimea (înălțimea): h

32 b) Rotație simplă stânga Se obține din situația simetrică celei prezentate mai sus: Starea inițială Starea finală Rotații duble Situațiile rezolvate de rotațiile duble sunt: Pentru a le analiza este nevoie să reprezentăm detaliat subarborele T2. Deoarece acesta are adâncimea h rezultă că are subarbori de adâncime h

33 Rotațiile duble au ca efect echilibrarea arborelui indiferent de subarborele (t2s sau t2d) în care este inserat nodul X. a) Rotație dublă stânga-dreapta Starea inițială Starea finală Numele de rotație dublă rezultă din faptul că starea finală poate fi atinsă aplicând două rotații simple: A doua rotație Starea inițială Prima rotație (simplă dreapta pt. A) (simpla stânga pt. B) Starea finală Inițial subarborii T1 și T3 au adâncimea h iar t2s si t2d au adâncimea 1 h. Valoarea inserată va mări adâncimea unuia din subarborii t2s sau t2d. În ambele cazuri se aplică mai intâi o rotație simplă spre stânga nodului B și apoi o rotație simplă spre dreapta nodului A. Rezultă un arbore echilibrat indiferent în care din subarborii t2s si t2d s-a făcut inserarea. Procedeul este corect și atunci când nodul inserat este nodul C și fiecare din subarborii T1, t2s, t2d, și T3 este arbore vid. Din nou trebuie notat faptul ca adâncimea arborelui rezultat este egală cu cea a arborelui inițial. -33-

34 b) Rotație dublă dreapta-stânga Se obține prin simetrie fată de situația de mai sus. Starea inițială Starea finală Aplicație În cele ce urmează se prezintă un program simplu C/C++ care implementează operațiile prezentate. #include <conio.h> #include <stdio.h> typedef int Atom; struct NAVL Atom data; char bf; NAVL *fst, *fdr; ; //adancimea unui arbore int depth(navl *a) if(a==0) return 0; int ms=1, md=1; ms = ms + depth(a->fst); md = md + depth(a->fdr); return (ms<md)? md : ms; //Rotatie simpla stanga NAVL *RotSStanga(NAVL *a) NAVL *b; b = a->fdr; a->fdr = b->fst; b->fst = a; a->bf = depth(a->fst) depth(a->fdr); //actualizeaza bf -34-

35 b->bf = depth(b->fst) depth(b->fdr); return b; //b devine noua rad //Rotatie simpla dreapta NAVL *RotSDreapta(NAVL *a) NAVL *b; b = a->fst; a->fst = b->fdr; b->fdr = a; a->bf = depth(a->fst) depth(a->fdr); b->bf = depth(b->fst) depth(b->fdr); return b; //b devine noua rad //rotatie dubla dreapta (stanga-dreapta) NAVL *RotDStDr(NAVL *a) a->fst = RotSStanga(a->fst); a = RotSDreapta(a); return a; //rotatie dubla stanga (dreapta-stanga) NAVL *RotDDrSt(NAVL *a) a->fdr = RotSDreapta(a->fdr); a = RotSStanga(a); return a; NAVL *InsAVL(NAVL *a, Atom x) if (a==0) a=new NAVL; a->data = x; a->fst=a->fdr=0; a->bf=0; return a; if(x < a->data) //insereaza in ramura stanga a->fst = InsAVL(a->fst, x); if((depth(a->fst) depth(a->fdr)) == 2) a = (x < a->fst->data)? RotSDreapta(a) : RotDStDr(a); a->bf = depth(a->fst) depth(a->fdr); //actualizeaza bf if(x > a->data) //insereaza in ramura dreapta a->fdr = InsAVL(a->fdr, x); if((depth(a->fst) depth(a->fdr)) == -2) a = (x > a->fdr->data)? RotSStanga(a):RotDDrSt(a); a->bf = depth(a->fst) depth(a->fdr); //actualizez bf -35-

36 return a; //AfisNod afiseaza arborele indentat void AfisNod(NAVL *r, int nivel) int i; for(i=0; i<nivel; i++) printf( \t ); if(r==0) printf( -\n ); //se tipareste - pentru ceva vid printf( %d\n, r->data); AfisNod(r->fst, nivel+1); AfisNod(r->fdr, nivel+1); void AfisArbore(NAVL *r) AfisNod(r,1); void crearearbore(navl *&r) Atom k; printf( Introduceti arborele (cheia coincide cu data), 0 exit\n ); do printf( data: ); scanf( %d, &k); if (k==0) break; r=insavl(r,k); while (1); void main () Atom val; NAVL *rad; rad=0; crearearbore(rad); AfisArbore(rad); printf( \nintroduceti valoarea de inserat: ); scanf( %d, &val); rad = InsAVL(rad, val); AfisArbore(rad); getch(); IC.06.7 IC Arbori binari de căutare optimali Introducere În cazul arborilor binari de căutare (BST Binary Search Tree), pentru un nod (sau cheie) oarecare, timpul de căutare este proporţional cu adâncimea nodului (distanţa de la acesta la rădăcină). Evident, unele chei sunt căutate mai des altele mai rar. Ar fi convenabil ca acele chei care sunt căutate mai des să fie plasate mai aproape de rădăcina arborelui, iar acele chei care sunt căutate mai rar să fie plasate mai departe de rădăcina arborelui. -36-

37 Dacă pentru fiecare dintre cheile unui arbore binar ordonat cunoaştem frecvenţa cu care această cheie va apărea în cadrul operaţiilor ulterioare de căutare, se pot construi arbori binari optimi pentru care cheile mai des căutate să fie plasate mai aproape de rădăcină. Frecvenţa de căutare poate fi privită şi ca probabilitatea ca o anumită cheie să fie ţinta unei operaţii viitoare de căutare în BST. Pentru un arbore binar ordonat conţinând cheile k1, k2, K, k, se consideră că fiecare n cheie k i are asociată o probabilitate de apariţie 0 p i 1, unde i= 1, K, n p1+ p2 + K + p n = 1 p i, respectând proprietăţile: Arborele binar ordonat poate fi numit optim (OBST) dacă: pi g nivel( k i) = minim (1) i Suma anterioară poartă numele de cost al arborelui sau drum ponderat, fiind suma drumurilor de la rădăcina la fiecare nod, ponderate cu probabilităţile de acces la noduri. Exemplu. Pentru un BST cu nodurile de chei 4, 5, 8, 10, 11, 12, 14 există mai multe topologii care să respecte proprietatea BST, printre care şi reprezentările din figura de mai jos a) 12 Fig. 1. Topologii ale unui BST b) Deşi reprezentarea din figura b) corespunde unui AVL, acest fapt nu garantează faptul că arborele este optimal în sensul definiţiei de mai sus. Arborele din figura a) poate fi optimal numai dacă frecvenţele de acces ale nodurilor sunt mai mari pentru nodurile de pe niveluri mici şi sunt mici pentru nodurile de pe niveluri mari. Putem admite că este posibil ca un BST degenerat să fie unul optimal. Mai apare o problemă: pe lângă frecvenţele de accesare a nodurilor existente în arbore (căutări încheiate cu succes), cum putem evidenţia căutările unor chei ce nu fac parte din arbore (căutări eşuate) şi cum le vom lua în considerare în construirea unui OBST? -37-

38 Pentru o astfel de abordare, vom porni de la Fig. 1 a) şi vom construi arborele extins corespunzător (fig. 2) E 7 E 0 E 1 E 2 E 3 E 4 12 E 5 E 6 Fig. 2. Arborele OBST extins Un BST extins se obţine dintr-un BST prin adăugarea nodurilor succesoare E i (noduri extinse sau fictive - marcate cu pătrate in fig. 2) la toate frunzele din arborele de la care am plecat. Un nod E i corespunde tuturor căutărilor eşuate pentru valori cuprinse în intervalul cheilor ( ki, k i + 1). Astfel, timpul de căutare pentru un element oarecare x este dat fie de adâncimea nodului de cheie x fie de adâncimea pseudonodului corespunzător intervalului dintre noduri care ar putea să-l conţină pe x. Notând cu q i probabilitatea de a căuta un nod de cheie x ce satisface relaţia ki < x< k i +, atunci costul unui BST se defineşte: 1 n C = p gnivel( k ) + q g ( nivel( E ) 1) (2) i i i i i= 1 i= 0 Expresia (nivel(e i )-1) în a doua sumă se justifică prin faptul că încadrarea unui nod x într-un interval se decide la nivelul părintelui unui pseudonod nu la nivelul pseudonodului. Pentru un BST optimal, valoarea lui C este minimă. Orice subarbore BST conţine cheile ordonate în domeniul kil k j pentru 1 i j n şi va avea propriile noduri fictive E i-1 E j. Problema construirii unui OBST revine la a construi subarbori optimali. Dacă k este rădăcina unui arbore optimal cu n chei, una din r cheile k1, K, kr va fi rădăcina subarborelui stâng şi una din cheile 1 k,, r+ 1 K k va fi rădăcina n n -38-

39 subarborelui drept (a se vedea figura de mai jos). Dacă rădăcinile celor doi subarbori se aleg astfel încât aceştia să fie optimali avem garanţia că arborele de rădăcină k r este optimal. k r p 1...p r-1 q 0...q r-1 p r+1...p n q r...q n k 1...k r-1 C(1,r-1) k r+1...k n Fig. 3. Subarbore optimal C(r+1,n) Ce se întâmplă când avem subarbori nuli? Dacă într-un subarbore cu cheile k i... k j găsim cheia k i ca fiind rădăcina subarborelui optimal vom aprecia că subarborele stâng conţine doar nodul fictiv E i-1 şi deci costul unei căutări pentru o cheie de valoare mai mică decât k i va depinde doar de q i-1. Dacă se notează cu C(i,j) costul unui subarbore optimal cu cheile k i,... k j, relaţia de calcul este: k 1 C(i,j) = min pk + qi-1+ ( pm + qm) + C( i,k 1) i k j m= i j + qk + pm + qm + + m= k+ 1 ( ) C( k 1,j) j = min C i,k 1 + C k + 1,j i k j ( ) ( ) q ( p q ) i-1 m m m= i În relaţia (3), i 1, j n şi j i-1. Cazul j=i-1 corespunde situaţiei subarborelui vid când se ia în considerare doar E i-1. Ultimul cost care va fi calculat este C(1,n): k 1 n C(1,n) = min pk + q0 + pi + qi + C 1,k 1 + qk + pi + qi + C k + 1,n 1 k n i= 1 i= k+ 1 ( ) ( ) ( ) ( ) (4) Această relaţie de recurenţă evidenţiază faptul că atunci când un arbore de cost minim devine subarbore al unui alt nod, nivelul (adâncimea) fiecărui nod din subarbore creşte cu 1 iar costul calculat anterior creşte cu suma tuturor probabilităţilor din subarbore. Dacă k r este rădăcina unui subarbore optimal de chei k i,... k j, relaţia (3) poate fi rescrisă: (3) -39-

40 ( ( ) ) ( ) ( ) C(i,j) = p + C i,k 1 + w( i, r 1) + C k + 1,j + w( r+ 1, j) r cu w(, i j) = w(, i r 1) + p + w( r + 1, j) rezulta C(, i j) = C(, i r 1) + C( r 1, j) + w(, i j) r (5) Relaţia de recurenţă de mai sus presupune că se ştie nodul de cheie k r ce urmează a fi rădăcină. Alegerea nodului rădăcină care va garanta cel mai mic cost conduce la următoarea relaţie pentru calculul recursive: min Cir (, 1) + Cr ( + 1, j) + wi (, j), daca i j; i r j ci (, j) = q j 1, daca j=i-1 (6) Pentru a putea construi structura OBST (evidenţa legăturilor între noduri şi descendenţi) se defineşte o matrice R(i,j) (1 i j n) care va memora indexul r pentru care k r este rădăcina unui OBST de chei k i... k j. Generarea un OBST O metodă primitivă de generare a unui OBST pentru un set de chei ar fi să se genereze toţi arborii de căutare posibili, să se calculeze costul fiecăruia şi să se reţină arborele de cost minim. Evident o astfel de abordare nu este fezabilă deoarece presupune un ordin de complexitate exponenţial. Din cele prezentate anterior este evident că un algoritm recursiv este o soluţie realistă. Pentru implementare se construiesc următoarele matrice: W i,j matricea ponderilor care se obţine cu relaţia: j. W = p + q i, j k k k=+ i 1 k= i Matricea W conţine pe diagonala principală elementele q j. C i,j matricea costurilor pentru OBST, ale cărei elemente se calculează conform relaţie (6): Cii, = Wii, ; C = W + min ( C + C ) i, j i, j i< k j i, k 1 k, j R i,j matricea ce conţine indexul cheii pentru care se obţine un minimum corespunzător în matricea C i,j. OBST(i,j) - reprezintă arborele optimal ce conţine cheile k i,...k j. Fiecare subarbore OBST(i,j) va avea rădăcina k Ri,j şi subarborii OBST(i,k-1) şi OBST(k+1,j). Exemplu de generare a unui OBST Până acum, teoria prezentată a făcut referire la probabilităţile p i de căutare cu succes a unei chei care se află într-un arbore ordonat şi q i probabilităţile eşuate de a nu găsi în arbore cheia căutată. Aceste probabilităţi se calculează uşor dacă se cunosc frecvenţele de accesare -40- j

41 ale nodurilor (cu sau fără succes) şi numărul total de noduri. In exemplu următor, vor fi utilizate frecvenţele de căutare, lăsând în seama studentului calcularea probabilităţilor (fapt ce nu este obligatoriu). Se va genera un arbore de căutare optimal, cu 6 noduri şi cu următoarele frecvenţe de căutare a cheilor şi între chei : Index K (Valoare cheie) p q Pas1. Se calculează matricea ponderilor W cu relaţiile de mai sus. Astfel se obţine: W (0, 0) = q0 = 5 W (0, 1) = q0 + q1 + p1 = = 21 W (1, 1) = q1 = 6 W (0, 2) = W (0, 1) + q2 + p2 = = 28 W (2, 2) = q2 = 4 W (0, 3) = W (0, 2) + q3 + p3 = = 41 W (3, 3) = q3 = 4 W (0, 4) = W (0, 3) + q4 + p4 = = 46 W (4, 4) = q4 = 3 W (0, 5) = W (0, 4) + q5 + p5 = = 54 W (5, 5) = q5 = 8 W (0, 6) = W (0, 5) + q6 + p6 = = 64 W (6, 6) = q6 = 0 W (1, 2) = W (1, 1) + q2 + p2 = = şi rezultă: W Deoarece suma elementelor vectorului p este 34 şi suma elementelor vectorului q este 30, suma tuturor accesărilor este 64, iar matricea W rescrisă în termeni de probabilitate este W': W' Pas. 2. Elementele de pe diagonala principală a matricei de cost sunt egale cu cele ale diagonalei principale din matricea ponderilor. Elementele de deasupra diagonalei principale se calculează cu relaţiile: C (0, 1) = W (0, 1) + (C (0, 0) + C (1, 1)) = = 32 C (1, 2) = W (1, 2) + (C (1, 1) + C (2, 2)) = = 23 C (2, 3) = W (2, 3) + (C (2, 2) + C (3, 3)) = = 25 C (3, 4) = W (3, 4) + (C (3, 3) + C (4, 4)) = =

42 C (4, 5) = W (4, 5) + (C (4, 4) + C (5, 5)) = = 22 C (5, 6) = W (5, 6) + (C (5, 5) + C (6, 6)) = = 26 Tot în acest pas, elementele de deasupra diagonalei principale din R se completează cu valorile indexului i din C(i,j). Pas 3. În continuare se calculează celelalte elemente ale matricei C conform relaţiilor de mai sus şi se completează a doua diagonală din matricea R cu indexul k aferent valorii de cost minim acele valori sunt subliniate in relaţiile de mai jos şi corespund valorilor minime scrise cu roşu. C (0, 2) = W (0, 2) + min (C (0, 0) + C (1, 2), C (0, 1) + C (2, 2)) = 28 + min (28, 36) = 56 C (1, 3) = W (1, 3) + min (C (1, 1) + C (2, 3), C (1, 2) + C (3, 3)) = 26 + min (31, 27) = 53 C (2, 4) = W (2, 4) + min (C (2, 2) + C (3, 4), C (2, 3) + C (4, 4)) = 22 + min (20, 28) = 42 C (3, 5) = W (3, 5) + min (C (3, 3) + C (4, 5), C (3, 4) + C (5, 5)) = 17 + min (26, 24) = 41 C (4, 6) = W (4, 6) + min (C (4, 4) + C (5, 6), C (4, 5) + C (6, 6)) = 21 + min (29, 22) = 43 C C Matricea costurilor după iteraţia a doua şi a treia Calculele continuă în aceeaşi manieră şi în final se obţin matricele C şi R de mai jos: Lungimea medie a drumului de căutare, numită şi costul arborelui de căutare sau lungimea de cale ponderată este egală cu max(c(i,j))/max(w(i,j))=c(0,6)/w(0,6). Pas 4. Construirea arborelui. Arborele de căutare optimal obţinut este prezentat în figura 4 de mai jos şi are un drum ponderat de 2,93=188/64. Calcul poziţiilor nodurilor în arbore se face astfel: rădăcina arborelui optimal are indexul cheii dat de R (0, 6)=3 K3 este cheia rădăcinii de valoare 10 şi frecvenţă de accesare 9; In general, dacă indexul rădăcinii unui arbore optimal este pe poziţia (i,j), atunci indexul cheii rădăcinii subarborelui stâng este pe poziţia (i,r(i,j)-1). In cazul considerat, indexul subarborelui stâng este dat de R(0, 2) =1 K1 este cheia nodului de valoare 3 şi frecvenţă de accesare 10; -42-

Arbori. 5 aprilie Utilizarea şi programarea calculatoarelor. Curs 16

Arbori. 5 aprilie Utilizarea şi programarea calculatoarelor. Curs 16 Arbori 5 aprilie 2004 Arbori 2 Noţiunea de arbore. Terminologie Arborii ne permit sǎ structurǎm ierarhic o mulţime de elemente structura de directoare şi fişiere într-un calculator arborele genealogic

More information

Alocarea memoriei în C sub Linux

Alocarea memoriei în C sub Linux Costel Aldea Alocarea memoriei în C sub Linux Sunt trei funcţii C standard care se pot folosi pentru a aloca memorie: malloc(), calloc(), si realloc(). Prototipurile lor, după cum sunt definite în stdlib.h:

More information

Se cer 2 variante: una cu implementarea statica si a doua cu implementarea dinamica a structurilor de date necesare. Comentati variantele.

Se cer 2 variante: una cu implementarea statica si a doua cu implementarea dinamica a structurilor de date necesare. Comentati variantele. Lucrarea 1 SDA 03.04.2017 Sa se realizeze urmatoarele programe, in limbaj C: 1. Se primesc de la intrarea standard: un numar k si un sir infinit de numere naturale a i. Se afiseaza la iesirea standard,

More information

Laborator 5 Instrucțiunile repetitive

Laborator 5 Instrucțiunile repetitive Laborator 5 Instrucțiunile repetitive Instrucțiunea for Instrucțiunea for permite repetarea unei secvențe de instrucțiuni atâta timp cât o condiție este îndeplinita. În plus, oferă posibilitatea execuției

More information

Probleme consultații 20 ianuarie 2018

Probleme consultații 20 ianuarie 2018 Algoritmi elementari Probleme consultații 20 ianuarie 2018 Problema 1: zerouri factorial Enunt Fiind dat un numar natural n, sa se determine numarul de cifre 0 cu care se termină factorialul numărului

More information

Utilizarea formularelor in HTML

Utilizarea formularelor in HTML Utilizarea formularelor in HTML Formulare Un formular este constituit din elemente speciale, denumite elemente de control (controls), cum ar fi butoane radio, butoane de validare, câmpuri text, butoane

More information

Fişiere in C++ Un fişier este o colecţie de date indicat printr-un nume şi o extensie. Numele este desparţit de extensie prin punct.

Fişiere in C++ Un fişier este o colecţie de date indicat printr-un nume şi o extensie. Numele este desparţit de extensie prin punct. Fişiere in C++ Un fişier este o colecţie de date indicat printr-un nume şi o extensie. Numele este desparţit de extensie prin punct. Avantajul lucrului cu fisiere este evident, datele rezultate în urma

More information

Tipuri de date structurate

Tipuri de date structurate Tipuri de date structurate Problema 1 Să se citească un șir A de la tastatură, citirea șirului se termina la introducerea valorii 0. Să se construiască și să se tipărească șirul B de perechi (element,

More information

1. Să se determine de câte ori apare cifra c în scrierea în baza p a numărului n.

1. Să se determine de câte ori apare cifra c în scrierea în baza p a numărului n. Observatii: Codul de mai jos a fost realizat si testat pe pagina online: https://www.tutorialspoint.com/compile_pascal_online.php 1. Să se determine de câte ori apare cifra c în scrierea în baza p a numărului

More information

13. ARBORI B Arbori B. Definiţie. Proprietăţi.

13. ARBORI B Arbori B. Definiţie. Proprietăţi. 13. ARBORI B 13.1 Arbori B. Definiţie. Proprietăţi. În cazul sistemelor de gestiune a bazelor de date relaţionale (SGBDR) este important ca pe lângă stocarea datelor să se realizeze şi regăsirea rapidă

More information

Fisiere text in Java.

Fisiere text in Java. Fisiere text in Java. Doru Anastasiu Popescu Prelucrarea fisierelor text in Java Aspecte teoretice: http://cursuri.cs.pub.ro/~poo/wiki/index.php/input/output http://upm.ro/intranet/ecalin/cd_educational/cd/javac/cap3.htm

More information

1 Laborator 3: Liste Circulare si Liste Dublu Inlantuite

1 Laborator 3: Liste Circulare si Liste Dublu Inlantuite 1.1 Obiective În lucrare sunt prezentate principalele operaţii asupra listelor circulare simplu înlănţuite: crearea, inserarea unui nod, ştergerea unui nod şi ştergerea listei. În a ua parte vor fi prezentate

More information

Stiva - continuare. Implementare prin listă înlănţuită. Lect. dr. Gabriela Trimbitas

Stiva - continuare. Implementare prin listă înlănţuită. Lect. dr. Gabriela Trimbitas Stiva - continuare Implementare prin listă înlănţuită 1 head T O R head T O R head NEW head O D R head O R D O R Ştergerea/Inserarea unui nod într-o stivă 2 Acest cod implementează TAD STIVĂ prin listă

More information

Rezolvare fişă de laborator Java Iniţiere în limbajul Java

Rezolvare fişă de laborator Java Iniţiere în limbajul Java Rezolvare fişă de laborator Java Iniţiere în limbajul Java Ex 1: Scrie următorul program Java folosind JCreator apoi încercă să-l înţelegi. public class primulprg System.out.println("Acesta este primul

More information

Ingineria Sistemelor de Programare. UML Diagrama Cazurilor de Utilizare 2016

Ingineria Sistemelor de Programare. UML Diagrama Cazurilor de Utilizare 2016 Ingineria Sistemelor de Programare UML Diagrama Cazurilor de Utilizare mihai.hulea@aut.utcluj.ro 2016 Introducere UML UML UML = Unified Modeling Language Dezvoltat in cadrul Object Management Group In

More information

Laborator 8 Java Crearea claselor de obiecte. Variabilele (campurile) clasei de obiecte

Laborator 8 Java Crearea claselor de obiecte. Variabilele (campurile) clasei de obiecte Laborator 8 Java Crearea claselor de obiecte. Variabilele (campurile) clasei de obiecte Probleme rezolvate: Scrieti, compilati si rulati toate exemplele din acest laborator: 1. Programul urmator (LotoConstante.java)

More information

Laborator 3 Java. Introducere in programarea vizuala

Laborator 3 Java. Introducere in programarea vizuala Laborator 3 Java Introducere in programarea vizuala 1. Pachetele AWT si Swing. 2. Ferestre 3.1. Introduceti urmatorul program JAVA: public class Pv public static void main(string args[ ]) JFrame fer=new

More information

Laborator 10. SGBD-ul MySQL (partea I)

Laborator 10. SGBD-ul MySQL (partea I) Laborator 10 SGBD-ul MySQL (partea I) 1. Introduceţi următoarea secvenţă PHP: $dbh = mysql_connect("localhost", "Costica", "mypass") or die("unable to connect to MySQL"); $selectdb = mysql_select_db('lucrudb');

More information

[LABORATOR DE PROGRAMARE C++] Aritoni Ovidiu. Algoritmi STL

[LABORATOR DE PROGRAMARE C++] Aritoni Ovidiu. Algoritmi STL Algoritmi STL 1. Prezentare generală 2. Clasificare: Algoritmi nechirurgicali ; Algoritmi chirurgicali ; Algoritmi de sortare; Algoritmi generali; 3. Algoritmi nechirurgicali (Non-mutating algorithms)

More information

Laborator 5 Sisteme Lindenmayer. Temă

Laborator 5 Sisteme Lindenmayer. Temă Laborator 5 Sisteme Lindenmayer. Temă 1. Parcurgerea unui pătrat. Următorul L-sistem Alfabet=F,+,-; Producţii= F -> F-F+F+F+F-F-F-F+F, + -> +, - -> - Axioma= F generează, cu interpretările standard (F

More information

Laborator 9. Programare orientată pe obiecte Laborator 9. 1) Să se realizeze o aplicaţie care să rezolve ecuaţii de gradul al doilea.

Laborator 9. Programare orientată pe obiecte Laborator 9. 1) Să se realizeze o aplicaţie care să rezolve ecuaţii de gradul al doilea. Laborator 9 1) Să se realizeze o aplicaţie care să rezolve ecuaţii de gradul al doilea. Interfaţa aplicaţiei va fi următoarea Casetelor text li se vor da denumirile: camp_a, camp_b, camp_c, rez. Evenimentului

More information

Probleme propuse pentru Testul de Laborator Semestrul I

Probleme propuse pentru Testul de Laborator Semestrul I Probleme propuse pentru Testul de Laborator Semestrul I Problema 1: Scrieti un program in C pentru rezolvarea ecuatiei de gradul 1 cu coeficienti reali. Valorile coeficientilor se citesc de la tastatura.

More information

Proprietati CSS pentru margini - BORDER

Proprietati CSS pentru margini - BORDER Proprietati CSS pentru margini - BORDER Property Values Description border border-bottom border-width border-bottom-width O proprietate pentru setarea celor 3 proprietati intr-o singura linie O proprietate

More information

Memorator funcţii predefinite C++ Funcţii matematice

Memorator funcţii predefinite C++ Funcţii matematice Funcţii matematice Funcţia Prototipul funcţiei Fişierul pow(x,y) double pow (double x,double y); long double pow ( long double x, long double y); float pow (float x,float y); double pow (double x, int

More information

Tehnici avansate de programare

Tehnici avansate de programare Tehnici avansate de programare Curs - Cristian Frăsinaru acf@infoiasi.ro Facultatea de Informatică Universitatea Al. I. Cuza Iaşi Adnotarea elementelor Tehnici avansate de programare p.1/1 Cuprins Ce sunt

More information

Introducere in AutoCAD 3D

Introducere in AutoCAD 3D Introducere in AutoCAD 3D Eu obisnuiesc sa spun ca diferenta dintre AutoCAD 2D si AutoCAD 3D este doar de 15 minute deoarece totul se reduce doar la a intelege cum functioneaza acest 3D si sistemul de

More information

Nivelul inferior de prelucrare a fişierelor

Nivelul inferior de prelucrare a fişierelor INTRĂRI ŞI IEŞIRI Operaţiile de I/E în limbajul C se realizează prin intermediul unor funcţii din biblioteca standard a limbajului. Majoritatea operaţiilor de I/E se realizează în ipoteza că datele sunt

More information

Programarea calculatoarelor

Programarea calculatoarelor Programarea calculatoarelor #3 C++ Elemente introductive ale limbajului C++ 2016 Adrian Runceanu www.runceanu.ro/adrian Curs 3 Elemente introductive ale limbajului C++ 02.11.2016 Curs - Programarea calculatoarelor

More information

Lucrarea nr.9 SUPRAÎNCĂRCAREA OPERATORILOR

Lucrarea nr.9 SUPRAÎNCĂRCAREA OPERATORILOR Lucrarea nr.9 SUPRAÎNCĂRCAREA OPERATORILOR Ca şi în C, limbajul C++ are posibilitatea supraîncărcării funcţiilor şi operatorilor. Mai exact, unei funcţii (metode) i se conferă posibilitatea de a înţelege

More information

Şiruri de caractere System.String string Verbatim verbatim verbatim Exemplu

Şiruri de caractere System.String string Verbatim verbatim verbatim Exemplu Şiruri de caractere Pentru reprezentarea şirurilor de caractere, în limbajul C#, tipul de date utilizat este clasa System.String (sau aliasul string). Se definesc două tipuri de şiruri: regulate de tip

More information

1. Funcţii referitoare la o singură înregistrare (single-row functions)

1. Funcţii referitoare la o singură înregistrare (single-row functions) Laborator 4 Limbajul SQL 1. Funcţii referitoare la o singură înregistrare (single-row functions) 2. Funcţii referitoare la mai multe înregistrări (multiple-row functions) 1. Funcţii referitoare la o singură

More information

Siruri de caractere. 1.1 Folosirea şirurilor

Siruri de caractere. 1.1 Folosirea şirurilor Informatica clasa a X-a 1 Siruri de caractere 1.1 Folosirea şirurilor Cea mai comună utilizare a tabloului unidimensional în limbajul C/C++ este şirul (de caractere). Spre deosebire de multe alte limbaje

More information

Îmbunătăţiri aduse în limbajul C++ facilităţilor standard ale limbajului C (cele care nu ţin de conceptele programării orientate obiect).

Îmbunătăţiri aduse în limbajul C++ facilităţilor standard ale limbajului C (cele care nu ţin de conceptele programării orientate obiect). Îmbunătăţiri aduse în limbajul C++ facilităţilor standard ale limbajului C (cele care nu ţin de conceptele programării orientate obiect). Supraîncărcarea numelui de funcţii (overloading) In C nu este permisa

More information

Tema 2 PL/SQL. 3. a. Creati o tabela numita emp_dup care să fie duplicata tabelei employees. Create table emp_dup as select * from employees

Tema 2 PL/SQL. 3. a. Creati o tabela numita emp_dup care să fie duplicata tabelei employees. Create table emp_dup as select * from employees Tema 2 PL/SQL 1. Ce va afişa acest bloc? fname varchar2(20); lname varchar2(15) default fernandez ; DBMS_OUTPUT.PUT_LINE(fname lname); a. Va printa fernandez. b. Va returna o eroare deoarece variabila

More information

1.Pentru definiţia de mai jos a subprogramului f, ce se afişează ca urmare apeluluif(121,1)? void f(long n, int i) { if(n!=0) if(n%3>0) { cout<<i;

1.Pentru definiţia de mai jos a subprogramului f, ce se afişează ca urmare apeluluif(121,1)? void f(long n, int i) { if(n!=0) if(n%3>0) { cout<<i; 1.Pentru definiţia de mai jos a subprogramului f, ce se afişează ca urmare apeluluif(121,1)? void f(long n, int i) { if(n!=0) if(n%3>0) { cout

More information

Laborator 1 Recursivitate

Laborator 1 Recursivitate Recursivitate 1. Fie ecuaţia x - Sx + P = 0 cu S, P R si x1, x rădăcinile ecuaţiei. Să se calculeze Sn=, n N. n n x 1 x Căutăm relaţia de recurenţă pentru Sn, ştiind că x1, respectiv x sunt rădăcinile

More information

Capitolul 8 Funcţii în limbajul C

Capitolul 8 Funcţii în limbajul C Obiectiv: stabilirea avantajelor pe care le aduce în programarea structurată folosirea funcţiilor. Activităţi: - Prezentarea funcţiilor definite de utilizator - Descrierea parametrilor formali şi a parametrilor

More information

LUCRAREA NR. 6 POINTERI

LUCRAREA NR. 6 POINTERI LUCRAREA NR. 6 POINTERI Un pointer este o variabilă care păstrează adresa unui obiect de tip corespunzător. Forma generală pentru declararea unei variabile pointer este: tip * nume_variabila; unde tip

More information

Lucrarea nr. 2. Funcţii şi structuri în C++

Lucrarea nr. 2. Funcţii şi structuri în C++ Lucrarea nr. 2 Funcţii şi structuri în C++ Pe măsură ce programele cresc in complexitate şi dimensiune, ele trebuiesc împărţite în fragmente mai mici şi mai uşor de gestionat numite funcţii. Funcţiile

More information

STRUCTURI DE DATE SI ALGORITMI LABORATOR 2 STIVA I. ASPECTE TEORETICE

STRUCTURI DE DATE SI ALGORITMI LABORATOR 2 STIVA I. ASPECTE TEORETICE STIVA I. ASPECTE TEORETICE O stiva este o lista simplu inlantuita gestionata conform principiului LIFO (Last In First Out). Conform acestui principiu, ultimul nod pus in stiva este primul nod care este

More information

Proiectarea bazelor de date. PL/SQL Proceduri în PL/SQL(partea II-a) # 9. Adrian Runceanu

Proiectarea bazelor de date. PL/SQL Proceduri în PL/SQL(partea II-a) # 9. Adrian Runceanu Proiectarea bazelor de date # 9 PL/SQL Proceduri în PL/SQL(partea II-a) 2016 Adrian Runceanu www.runceanu.ro/adrian Curs 9 Proceduri în PL/SQL Proiectarea bazelor de date 2 Cuprins Proceduri în PL/SQL

More information

Aplicații JAVA. Lect.dr. Adrian Runceanu

Aplicații JAVA. Lect.dr. Adrian Runceanu Universitatea Constantin Brâncuşi din Târgu-Jiu Facultatea de Inginerie Departamentul de Automatică, Energie şi Mediu Aplicații JAVA Lect.dr. Adrian Runceanu Curs 6 Colecții în Java 01.04.2015 Curs - Aplicatii

More information

Operatori. Comentarii. Curs 1

Operatori. Comentarii. Curs 1 Operatori atribuirea: = operatori matematici: +, -, *, /, % Este permisa notatia prescurtata de forma lval op= rval (ex: n += 2) Exista operatorii pentru autoincrementare si autodecrementare (post si pre)

More information

CONFIGURAREA UNUI SERVER IRC IN LINUX. Bica Bogdan *

CONFIGURAREA UNUI SERVER IRC IN LINUX. Bica Bogdan * CONFIGURAREA UNUI SERVER IRC IN LINUX Bica Bogdan * In this exemple i show how to configure an irc server based on ircd dameon named ircu.this is the main file name ircd.conf and the most important.configure

More information

Operații de intrare/ieșire în C++

Operații de intrare/ieșire în C++ Operații I/O în limbajul C++ Operații de intrare/ieșire în C++ Mihai Gabroveanu Limbajul C++ moștenește de la C funcțiile de I/O Dezavantaj: permit manipularea doar a tipurilor de bază Limbajul C++ introduce

More information

Lenuta Alboaie Reţele de calculatoare

Lenuta Alboaie Reţele de calculatoare Programarea in retea - OOB- Lenuta Alboaie adria@info.uaic.ro 1 Cuprins Trimiterea si receptarea datelor in regim 2 Ideea: in timpul unei conexiuni cind sunt transmise date ( inband data ), si daca la

More information

8. Tablouri. 8.1 Tipuri de dată simple şi tipuri de dată structurate

8. Tablouri. 8.1 Tipuri de dată simple şi tipuri de dată structurate 8. Tablouri Tablourile (arrays) reprezintă un tip important de structură de date şi sunt colecţii de obiecte de acelaşi tip reunite sub un singur nume. Uneori este necesar să referim anumite variabile

More information

COLEGIUL TEHNIC VICTOR UNGUREANU CÂMPIA TURZII INSTALAREA SI CONFIGURAREA UNUI SERVER DNS PE WINDOWS SERVER 2003

COLEGIUL TEHNIC VICTOR UNGUREANU CÂMPIA TURZII INSTALAREA SI CONFIGURAREA UNUI SERVER DNS PE WINDOWS SERVER 2003 INSTALAREA SI CONFIGURAREA UNUI SERVER DNS PE WINDOWS SERVER 2003 DNS (Domain Name Service) este un protocol care translateaza numele de domenii in adrese IP. De exemplu numele de domeniu www.google.ro

More information

Tablouri de date. Tablouri unidimensionale(siruri de date sau vectori)

Tablouri de date. Tablouri unidimensionale(siruri de date sau vectori) Tablouri de date Tablouri unidimensionale(siruri de date sau vectori) I. Operaţii asupra şirurilor de date monodimensionale Definiţie Tablou = succesiune de locaţii de memorie recunoscute prin acelaşi

More information

Laborator 4 Java Colectii

Laborator 4 Java Colectii Laborator 4 Java Colectii Scrieti, compilati si rulati toate exemplele din acest laborator: 1. Urmatorul exemplu foloseste diferite clase de colectii si adauga cate un element in aceste colectii import

More information

Capitolul 4. Subnivelul Controlul Accesului la Mediu (MAC=Medium Access Control)

Capitolul 4. Subnivelul Controlul Accesului la Mediu (MAC=Medium Access Control) Capitolul 4 Subnivelul Controlul Accesului la Mediu (MAC=Medium Access Control) 1 The Channel Allocation Problem Static Channel Allocation in LANs and MANs Dynamic Channel Allocation in LANs and MANs Alocare

More information

JavaScript - Intorducere. Și nu numai...

JavaScript - Intorducere. Și nu numai... JavaScript - Intorducere Și nu numai... Ce facem azi Nu o sa va vină să credeți. Pe foaia albă vă scrieți numele și prenumele ȘI Povestim despre JavaScript Exemple de aplicare discutii și surprize mici

More information

Colorarea cografurilor folosind descompunerea modulară

Colorarea cografurilor folosind descompunerea modulară Colorarea cografurilor folosind descompunerea modulară Cristian Frăsinaru acf@infoiasi.ro Facultatea de Informatică Universitatea Al. I. Cuza Iaşi 1 Cuprins 1 Descompunerea modulară 3 1.1 Definiţii..............................

More information

Structuri Bazele structurilor

Structuri Bazele structurilor 1. Bazele structurilor 2. Structurile şi funcțiile 3. Transmiterea structurilor ca argumente 4. Structurile şi pointerii 5. Tablouri de structuri 6. Pointerii spre structuri 7. Typedef 8. Alocarea dinamică

More information

Laborator 1 Java. Citirea datelor de la tastatura si afisarea datelor pe ecran

Laborator 1 Java. Citirea datelor de la tastatura si afisarea datelor pe ecran Laborator 1 Java Citirea datelor de la tastatura si afisarea datelor pe ecran In limbajul Java nu exista instructiuni specializate pentru citirea/scrierea datelor. Aceste operatii se realizeaza prin intermediul

More information

Tipuri structurate de date definite de utilizator

Tipuri structurate de date definite de utilizator Tipuri structurate de date definite de utilizator Problema 1. Jucarii Scrieti o aplicatie care il ajuta pe Mos Craciun sa tina evidenta: Jucariilor: idjucarie, denumirejucarie, dimensiunejucarie Copiilor:

More information

Programarea calculatoarelor

Programarea calculatoarelor Limbajul C CURS 3 Instrucţiuni C continuare curs 2 Alte instrucţiuni C Instrucţiunea break >ieşire forţată din ciclu sau switch Salt după instrucţiunea din care a ieşit Instrucţiunea continue ->continuă

More information

Programarea calculatoarelor

Programarea calculatoarelor Universitatea Constantin Brâncuşi din Târgu-Jiu Facultatea de Inginerie Departamentul de Automatică, Energie şi Mediu Programarea calculatoarelor Lect. dr. Adrian Runceanu Curs 10 13.11.2013 Programarea

More information

Proiectarea Rețelelor 32. Controlul modelelor de trafic in retea prin alterarea atributelor BGP

Proiectarea Rețelelor 32. Controlul modelelor de trafic in retea prin alterarea atributelor BGP Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Proiectarea Rețelelor 32. Controlul modelelor de trafic in retea prin alterarea atributelor BGP De ce ebgp? De ce ibgp?

More information

Instructiuni de control

Instructiuni de control Instructiuni de control Introducerea caracterelor de la tastatura Instructiuni de selectie (if, switch) Instructiuni repetitive (for, while, dowhile, foreach) Instructiuni de salt (break, continue, goto,

More information

Hierarchical organization of information, in relational databases

Hierarchical organization of information, in relational databases Hierarchical organization of information, in relational databases Demian Horia University of Oradea, Faculty of Economics, No 1, University Street, 410087, Bihor, Tel. 0259 408 796 email: horia_demian@yahoo.com

More information

Capitolul IB.03. Funcţii de intrare/ieşire în limbajul C

Capitolul IB.03. Funcţii de intrare/ieşire în limbajul C Capitolul Cuvinte-cheie Funcţii de intrare/ieşire caractere, funcţii de intrare/ieşire şiruri de caractere, citire/scriere cu format IB.03.1 Funcţii de intrare/ieşire în C În limbajul C, nu există instrucţiuni

More information

Proiectarea bazelor de date

Proiectarea bazelor de date Universitatea Constantin Brâncuşi din Târgu-Jiu Facultatea de Inginerie Departamentul de Automatică, Energie şi Mediu Proiectarea bazelor de date Lect.univ.dr. Adrian Runceanu 19.03.2013 Proiectarea bazelor

More information

Proiectarea Rețelelor 1. Componentele hardware ale unui sistem de calcul

Proiectarea Rețelelor 1. Componentele hardware ale unui sistem de calcul Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Proiectarea Rețelelor 1. Componentele hardware ale unui sistem de calcul Integrated IS-IS 25 Noiembrie 2010 Proiectarea

More information

GDB. Rulare gdb. Comenzi de bază GDB GDB. GDB poate fi folosit în două moduri pentru a depana programul:

GDB. Rulare gdb. Comenzi de bază GDB GDB. GDB poate fi folosit în două moduri pentru a depana programul: GDB GDB Rulare gdb GDB poate fi folosit în două moduri pentru a depana programul: rulându-l folosind comanda gdb folosind fişierul core generat în urma unei erori grave (de obicei segmentation fault) Cea

More information

Capitolul 4. Fisiere de date si Tablespace. F. Radulescu. Curs: Utilizarea bazelor de date, anul IV C5.

Capitolul 4. Fisiere de date si Tablespace. F. Radulescu. Curs: Utilizarea bazelor de date, anul IV C5. Capitolul 4 Fisiere de date si Tablespace 1 Continut capitol Ca structura fizica, baza de date contine fisiere de control, de date si de Redo log. Ca structura logica o baza de date se compune din: Tablespace

More information

PROGRAMARE ORIENTATĂ PE OBIECTE

PROGRAMARE ORIENTATĂ PE OBIECTE Universitatea Constantin Brâncuşi din Târgu-Jiu Facultatea de Inginerie Departamentul de Automatică, Energie şi Mediu PROGRAMARE ORIENTATĂ PE OBIECTE Lector dr. Adrian Runceanu 03.01.2014 1 Curs 15 Limbajul

More information

Programarea calculatoarelor. C++ Siruri de caractere # 10. Adrian Runceanu

Programarea calculatoarelor. C++ Siruri de caractere # 10. Adrian Runceanu Programarea calculatoarelor # 10 C++ Siruri de caractere 2016 Adrian Runceanu www.runceanu.ro/adrian Curs 10 21.11.2016 Programarea calculatoarelor 2 Capitolul 8. Şiruri de caractere 8.1. Formă generală.

More information

Gestionarea memoriei dinamice. Tablouri şi şiruri de caractere. Conversii de date. Operaţii de intrare / ieşire

Gestionarea memoriei dinamice. Tablouri şi şiruri de caractere. Conversii de date. Operaţii de intrare / ieşire Lucrarea 3 Gestionarea memoriei dinamice. Tablouri şi şiruri de caractere. Conversii de date. Operaţii de intrare / ieşire Cuprins Simbolul this...1 Colectorul de reziduuri (Garbage Collector)...4 Transmiterea

More information

Rezolvarea exceptiilor

Rezolvarea exceptiilor PL/SQL SECTIUNE 6 Rezolvarea exceptiilor Entering an incorrect username and/or password Forgetting to include the @ in an email address Entering a credit card number incorrectly Entering an expiration

More information

Lucrarea de laborator nr. 4.NET Remoting 1

Lucrarea de laborator nr. 4.NET Remoting 1 Lucrarea de laborator nr. 4.NET Remoting 1 4. Implementarea claselor Well Known (Server Activated) In cadrul acestei lucrari de laborator vom realiza cateva aplicatii care vor exemplifica conceptele fundamentale

More information

Facultatea de Matematică și Informatică Lecții de pregătire Admitere FMI

Facultatea de Matematică și Informatică Lecții de pregătire Admitere FMI Facultatea de Matematică și Informatică Lecții de pregătire Admitere FMI Graf neorientat: G = (V, E) vârf (nod), muchie gradul unui vârf vârfuri adiacente lanţ ciclu distanță Graf neorientat: G = (V,

More information

SECTION 5 L1 - Group By and Having Clauses

SECTION 5 L1 - Group By and Having Clauses SECTION 5 L1 - Group By and Having Clauses Clauza Group By 1. SELECT department_id, AVG(salary),MAX(salary) 2. SELECT job_id, last_name, AVG(salary) GROUP BY job_id; ORA-00979: not a GROUP BY expression

More information

Curs 5. Programare Paralela si Distribuita. Forme de sincronizare - Java. Curs 5 - PPD 1

Curs 5. Programare Paralela si Distribuita. Forme de sincronizare - Java. Curs 5 - PPD 1 Curs 5 Programare Paralela si Distribuita Forme de sincronizare - Java Curs 5 - PPD 1 Monitor in Java Fiecare obiect din Java are un mutex care poate fi blocat sau deblocat in blocurile sincronizate: Bloc

More information

Capitolul 4. Fisiere de date si Tablespace. F. Radulescu. Curs: Utilizarea bazelor de date, anul IV C5.

Capitolul 4. Fisiere de date si Tablespace. F. Radulescu. Curs: Utilizarea bazelor de date, anul IV C5. Capitolul 4 Fisiere de date si Tablespace 1 Continut capitol Ca structura fizica, baza de date contine fisiere de control, de date si de Redo log. Ca structura logica o baza de date se compune din: Tablespace

More information

Lucrarea de laborator nr. 5

Lucrarea de laborator nr. 5 Mete Numerice Lucrarea de laborator nr. 5 I. Scopul lucrării Aplicaţii ale eliminării gaussiene cu pivotare parţială: - calculul determinantului unei matrice - rezolvarea sistemelor liniare - calculul

More information

Scop: Crearea unei aplicatii ce exemplifica paternul MVVM. In plus se creaza si o comanda in WPF.

Scop: Crearea unei aplicatii ce exemplifica paternul MVVM. In plus se creaza si o comanda in WPF. Laborator MVVM Scop: Crearea unei aplicatii ce exemplifica paternul MVVM. In plus se creaza si o comanda in WPF. Clasele implicate in acest pattern sunt date in figura de mai jos. Mai multe informatii

More information

Suport curs Web design nivel 1

Suport curs Web design nivel 1 Partea 1 - Ce inseamna HTML? Pentru inceput sa descoperim originea abrevierii HTML - HyperText Markup Language. Acest limbaj este folosit pentru a formata si prezenta documente pe web. HTML adauga tag-uri

More information

Curs 14 Colectii. Ce sunt colectiile? Interfete ce descriu colectii. Curs 14. Ce sunt colectiile? Interfetele de baza care descriu colectii

Curs 14 Colectii. Ce sunt colectiile? Interfete ce descriu colectii. Curs 14. Ce sunt colectiile? Interfetele de baza care descriu colectii Curs 14 Colectii Ce sunt colectiile? Interfetele de baza care descriu colectii o Collection o Set o List o Map o SortedSet o SortedMap Implementari ale colectiilor Folosirea eficienta a colectiilor Algoritmi

More information

Limbaje de tipul 3. Gramatici regulate Automate finite. Expresii regulate. Deterministe Nedeterministe. a, a, ε, E 1.E 2, E 1 E 2, E 1*, (E 1 )

Limbaje de tipul 3. Gramatici regulate Automate finite. Expresii regulate. Deterministe Nedeterministe. a, a, ε, E 1.E 2, E 1 E 2, E 1*, (E 1 ) Curs 7 1 Limbaje de tipul 3 Gramatici regulate Automate finite Deterministe Nedeterministe Expresii regulate a, a, ε, E 1.E 2, E 1 E 2, E 1*, (E 1 ) 2 Istoric Paşii compilării Analiza lexicală Descriere

More information

Fișiere de comenzi (BAT) sub DOS

Fișiere de comenzi (BAT) sub DOS L3 Fișiere de comenzi (BAT) sub DOS Un fișier de comenzi este un fisier text care conține una sau mai multe comenzi si / sau directive care se execută succesiv, fară intervenția directă a utilizatorului.

More information

Variabile predefinite

Variabile predefinite Php(2) Variabile predefinite Variabile predefinite $GLOBALS = pot fi accesate toate variabilele globale care sunt accesibile scriptului PHP curent $_SERVER = contine o serie de variabile ale caror valori

More information

TP-LINK TL-MR3220 3G 150MB/S Router wireless Lite-N 150Mbps Manual de utilizare

TP-LINK TL-MR3220 3G 150MB/S Router wireless Lite-N 150Mbps Manual de utilizare TP-LINK TL-MR3220 3G 150MB/S Router wireless Lite-N 150Mbps Manual de utilizare 1. Conectarea router-ului Pentru configurarea router-ului, utilizati numai conexiunea de retea prin cablu. a. Deconectati

More information

la Microsoft Office Communicator pentru ca modificarea selecţiei dispozitivului telefonic să se actualizeze.

la Microsoft Office Communicator pentru ca modificarea selecţiei dispozitivului telefonic să se actualizeze. QUICK START GUIDE Plug-in de selec ie a telefonului pentru caracteristica de control al apelurilor din Microsoft Office Communicator pentru Cisco Unified Presence versiunea 7.0(3) Prezentare generală 2

More information

Design activities. Session III. 1. Topology. - Selecting and placing devices - Interconnecting devices

Design activities. Session III. 1. Topology. - Selecting and placing devices - Interconnecting devices Design activities Session I 1. Topology - Selecting and placing devices - Interconnecting devices 2. Providing connectivity between directly connected devices - Configuring addresses for servers and hosts

More information

1. Sa se deseneze un circuit logic care corespunde urmatoarelor forme de unda (A si B sunt intrari, X este iesirea)

1. Sa se deseneze un circuit logic care corespunde urmatoarelor forme de unda (A si B sunt intrari, X este iesirea) 1. Sa se deseneze un circuit logic care corespunde urmatoarelor forme de unda (A si B sunt intrari, X este iesirea) 2. Sa se implementeze functia logica data de urmatorul tabel de adevar folosind numai

More information

Programarea calculatoarelor

Programarea calculatoarelor Universitatea Constantin Brâncuşi din Târgu-Jiu Facultatea de Inginerie Departamentul de Automatică, Energie şi Mediu Programarea calculatoarelor Lect. dr. Adrian Runceanu Curs 10 05.05.2014 Programarea

More information

Introducere în C B. Kernighan, D. Richie-Limbajul C 1. Despre C. Primul program

Introducere în C B. Kernighan, D. Richie-Limbajul C 1. Despre C. Primul program B. Kernighan, D. Richie-Limbajul C 1. Despre C. Primul program 2. Variabile şi expresii aritmetice 3. Instrucțiunea for 4. Constante simbolice 5. Citirea şi scrierea caracterelor 6. Tablouri 7. Funcții

More information

Laborator 2 Java. Structura programelor Java. Tipuri de date. Probleme rezolvate: Scrieti, compilati si rulati toate exemplele din acest laborator:

Laborator 2 Java. Structura programelor Java. Tipuri de date. Probleme rezolvate: Scrieti, compilati si rulati toate exemplele din acest laborator: Laborator 2 Java Structura programelor Java. Tipuri de date. Probleme rezolvate: Scrieti, compilati si rulati toate exemplele din acest laborator: 1. Se citeste un numar n natural. Sa se calculeze suma

More information

Error! Bookmark not defined.

Error! Bookmark not defined. SEMINAR 06 CONTENTS Enuntul Problemei... 1 Repository... 2 Memory... 2 XML... 3 GUI... 4 Forma Selectie... 4 Forma Programator... 5 Forma Tester... 6 Java... 7 Mecanismul de Transmitere al Evenimentelor

More information

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Transmisia datelor multimedia in retele de calculatoare 28. O scurta istorie a compresiei audio: MPEG-1, MPEG-2, MPEG-

More information

Aplicatii JAVA. JAVA Excepții în Java # 7. Adrian Runceanu

Aplicatii JAVA. JAVA Excepții în Java # 7. Adrian Runceanu Aplicatii JAVA # 7 JAVA Excepții în Java 2017 Adrian Runceanu www.runceanu.ro/adrian Curs 7 Excepții în Java 24.03.2017 Curs - Aplicatii Java 2 Excepții în Java 1. Ce sunt excepțiile? 2. Avantajele excepțiilor

More information

1. Citirea datelor de la tastatura si afisarea datelor pe ecran

1. Citirea datelor de la tastatura si afisarea datelor pe ecran Laborator 6 Java 1. Citirea datelor de la tastatura si afisarea datelor pe ecran In limbajul Java nu exista instructiuni specializate pentru citirea/scrierea datelor. Aceste operatii se realizeaza prin

More information

8.Comenzi AT pentru module Bluetooth

8.Comenzi AT pentru module Bluetooth 8.Comenzi AT pentru module Bluetooth Cuprins Laborator 8 8.1. Transmisia datelor prin Bluetooth 8.2. Desfăşurarea lucrării 8.3.Lista de comenzi AT Cuprins Introducere Ultima lucrare catre tratează comenzile

More information

Elemente de bază ale limbajului C++

Elemente de bază ale limbajului C++ Elemente de bază ale limbajului C++ 1. Vocabularul limbajului Elementele de bază ale limbajului, numite şi entităţi sintactice sau atomi lexicali, fac parte din următoarele categorii : cuvinte rezervate

More information

POO. Observer Pattern (prezentare bazata pe GoF)

POO. Observer Pattern (prezentare bazata pe GoF) POO Observer Pattern (prezentare bazata pe GoF) 1 Observator: :intentie Defineste o relatie de dependenta 1..* intre obiecte astfel incat cand un obiect isi schimba starea, toti dependentii lui sunt notificati

More information

PNI SmartCAM. versiune Android. - manual de utilizare-

PNI SmartCAM. versiune Android. - manual de utilizare- PNI SmartCAM versiune Android - manual de utilizare- Introducere: Acest manual se refera la instalarea si utilizarea aplicatiei PNI SmartCAM, software necesar monitorizarii atat camerei cu IP PNI 631W,

More information

Fisa de lucru: Studiul componentelor calculatorului

Fisa de lucru: Studiul componentelor calculatorului 11.3.7 Fisa de lucru: Studiul componentelor calculatorului Imprimati si completati aceasta activitate. In aceasta activitate veti folosi Internet-ul, un ziar, sau un magazin local pentru a culege informatii

More information

XML SCHEMA Prezentare

XML SCHEMA Prezentare XML SCHEMA Prezentare 1. Despre XML Schema scurta istorie 2. XML Schema vs. DTD 3. Sintaxa 4. Cazuri de utilizare 5. Tooluri 6. Concluzii 7. Bibliografie 1. Despre XML Schema scurta istorie XML Schema

More information

Şirurile de caractere sunt de fapt succesiuni de caractere. Am învăţat deja să memorăm succesiuni de caractere cu ajutorul tablourilor.

Şirurile de caractere sunt de fapt succesiuni de caractere. Am învăţat deja să memorăm succesiuni de caractere cu ajutorul tablourilor. 3. Şiruri de caractere 3.1. Declararea şi memorarea vectorilor de caractere Şirurile de caractere sunt de fapt succesiuni de caractere. Am învăţat deja să memorăm succesiuni de caractere cu ajutorul tablourilor.

More information