Documente Academic
Documente Profesional
Documente Cultură
1. Arbori binari.........................................................................................................................3 1.1. Crearea i parcurgerea RSD, SRD, SDR (afiarea) unui arbore binar..........................6 1.2. tergerea unui nod dintr-un arbore binar.....................................................................10 1.3. Inserarea unui nod ntr-un arbore binar.......................................................................12 1.4. Numrarea nodurilor i determinarea numrului de niveluri......................................14 1.5. Programul complet......................................................................................................15
1. Arbori binari
Un arbore binar este un arbore n care fiecare vrf are cel mult doi descendeni fcndu-se distincie clar ntre descendentul drept i descendentul stng al fiecrui vrf. Pentru discuiile referitoare la arbori este necesar o terminologie special: fiecare element este numit nod; primul element dintr-un arbore se numete rdcin; celelalte noduri formeaz fiecare cte un arbore; aceti arbori se numesc subarbori; ntr-un arbore exist noduri crora nu le mai corespund subarbori; un astfel de nod se numete nod terminal sau frunz; un nod rdcin este numit nod tat; rdcina unui subarbore se numete nod fiu; rdcina unui arbore se afl pe nivelul 1; dac un nod are nivelul m atunci fii lui au nivelul m + 1; prin nlimea arborelui nelegem numrul total de niveluri al unui arbore determin . Un arbore binar n care fiecare nod care nu este terminal are exact doi descendeni se numete arbore binar complet. Pentru utilizarea nodurilor unui arbore binar vom folosi o structura cu urmtoarele cmpuri: inf informaia coninuta in nod st adresa nodului descendent stng; dr adresa nodului descendent drept.
Prin parcurgerea (traversarea) unui arbore se nelege examinarea n mod sistematic a nodurilor sale astfel nct fiecare nod sa fie parcurs o singura dat. Exist trei moduri de parcurgere (recursiv) a arborilor binari: a) Preordine (RSD) se viziteaz rdcina; se traverseaz arborele stng; se traverseaz arborele drept. c) Postordine (SDR) se traverseaz arborele stng; se traverseaz arborele drept; se viziteaz rdcina. b) Inordine (SRD) se traverseaz arborele stng; se viziteaz rdcina; se traverseaz arborele drept.
1, 2, 4, 5, 3, 6, 7, 8; 4, 5, 2, 1, 6, 3, 8, 7; 5, 4, 2, 6, 8, 7, 3, 1.
1.1. Crearea i parcurgerea RSD, SRD, SDR (afiarea) unui arbore binar
# # # # # include <stdio.h> include <conio.h> include <alloc.h> include <stdlib.h> define NEW (NOD*)malloc(sizeof(NOD));
struct NOD { int inf; struct NOD *st,*dr; }; /////////////////// Crearea arborelui by nec NOD *creare() { NOD *p; int nr; p=NEW; printf("Nr="); scanf("%d",&nr); p->inf=nr; p->st=NULL;
Arbori binari (C++ partea 6) p->dr=NULL; printf("Introducem arbore in stanga pentru nodul cu informatia %d (d/n)? \n",nr); if(getch()=='d') p->st=creare(); printf("Introducem arbore in dreapta pentru nodul cu informatia %d (d/n)? \n",nr); if(getch()=='d') p->dr=creare(); return p;} /////////////////// Parcurgerea RSD arborelui by nec void parc_preord (NOD *p) { if(p!=NULL) { printf("\t Nr=%d", p->inf); parc_preord(p->st); parc_preord(p->dr); } } /////////////////// Parcurgerea SRD arborelui by nec void parc_inord (NOD *p) { if(p!=NULL) { parc_inord(p->st); printf("\t Nr=%d", p->inf); parc_inord(p->dr); } }
/////////////////// Parcurgerea SDR arborelui by nec void parc_postord (NOD *p) { if(p!=NULL) { parc_postord(p->st); parc_postord(p->dr); printf("\t Nr=%d", p->inf); } } Nchil Ctlin Laborator UPG 7
Arbori binari (C++ partea 6) /////////////////// Stergerea arborelui by nec void stergarbore(NOD *p) { if (p!=NULL) { stergarbore(p->st); stergarbore(p->dr); delete p; } } /////////////////// Afisare spatii by nec void spatii(int n) { int i; for(i=0;i<n;i++) putchar(' '); } /////////////////// Afisare arbore by nec void afisare(int n, int f, int k, int vb, int *vn) { int i; spatii(4); if(n) { for(i=1;i<n;i++) { if(vn[i]) putchar(' '); else putchar('|'); spatii(4); } if(f) putchar('|'); else putchar('|'); for(i=0;i<4;i++) putchar('-'); } if(vb) printf("%d\n",k); else printf("...\n"); }
/////////////////// Afisare pe niveluri by nec void afisare_nivel (NOD *p, int n=0) { static int vn[50],f=1; if(p) { afisare(n,f,p->inf,1,vn); if(p->st || p->dr) { f=1; vn[n+1]=0; afisare_nivel(p->st,n+1); } if(p->st || p->dr) { f=0; vn[n+1]=1; afisare_nivel(p->dr,n+1); } } else afisare(n,f,10,0,vn);} /////////////////// Programul principal by nec void main() {NOD *rad; int nr,nivel,nrnou,nrsters; clrscr(); rad=creare(); printf("--------------------------------------------------- \n"); printf("Parcurgere preordine \n"); parc_preord(rad);printf("\n"); printf("Parcurgere inordine \n"); parc_inord(rad);printf("\n"); printf("Parcurgere postordine \n"); parc_postord(rad);printf("\n"); printf("\n"); printf("Afisarea pe niveluri: \n"); afisare_nivel(rad); Nchil Ctlin Laborator UPG 9
Cazul 2) Nodul de ters are doi fii . Nodul respectiv nu se va terge fizic.Informaia lui va fi nlocuit cu informaia celui mai din stnga nod al subarborelui drept sau cu informaia a celui mai din dreapta nod al subarborelui stng, care apoi va fi ters (nodul are informaia imediat mai mare, respectiv imediat mai mic, dect informaia nodului ce va trebui ters, deci arborele n ansamblu va rmne tot de cutare) (funcia din program este sterg):
Funcia va returna informaia nodului care se va terge fizic pentru a nlocui informaia nodului cutat pentru a fi ters. Nchil Ctlin Laborator UPG 10
Funcia de tergere a unui nod este: ///////////////// Stergerea unui nod cu doi descendenti by nec int sterg(NOD *&pa) { if(pa->st) return sterg(pa->st); else { NOD *a=pa; int k=a->inf; pa=pa->dr; free(a); return k; } } ///// Stergerea unui nod cu cel putin nu descendent vid by nec void stergerenod(NOD *& p, int k) { NOD *aux; if(p==NULL) printf("\n Nodul %d nu exista ",p->inf); else if(k<p->inf) stergerenod(p->st,k); else if(k>p->inf) stergerenod(p->dr,k); else { aux=p; if(!aux->dr) { p=aux->st; free(aux); } else if(!aux->st) { p=aux->dr; free(aux); } else p->inf=sterg(p->dr); } } Nchil Ctlin Laborator UPG 11
Arbori binari (C++ partea 6) n programul principal se va aduga secvena: printf("----------------------------------------------- \n"); printf("Nodul care se sterge = "); scanf("%d",&nrsters); stergerenod(rad,nrsters); printf("Parcurgere preordine \n"); parc_preord(rad);printf("\n"); printf("Parcurgere inordine \n"); parc_inord(rad);printf("\n"); printf("Parcurgere postordine \n"); parc_postord(rad);printf("\n"); printf("Afisarea pe niveluri: \n"); afisare_nivel(rad);
12
Funcia de inserare a unui nod este: /////////////////// Inserare nod by nec void inserare(NOD *&p,int x) {NOD *pnou; if (p==NULL) { pnou=NEW pnou->inf=x; pnou->st=NULL; pnou->dr=NULL; p=pnou; } else if (p->inf>x) inserare(p->st,x); else if (p->inf<x) inserare(p->dr,x); else printf("Elementul deja exista! \n"); } n programul principal se va aduga secvena: printf("--------------------------------------------------- \n"); printf("Numarul de inserat este="); scanf("%d",&nrnou); inserare(rad,nrnou); printf("Parcurgere preordine \n"); parc_preord(rad);printf("\n"); printf("Parcurgere inordine \n"); parc_inord(rad);printf("\n"); printf("Parcurgere postordine \n"); parc_postord(rad);printf("\n"); printf("Afisarea pe niveluri: \n"); afisare_nivel(rad);
13
14
15
/////////////////// Parcurgerea SRD arborelui by nec void parc_inord (NOD *p) { if(p!=NULL) { parc_inord(p->st); printf("\t Nr=%d", p->inf); parc_inord(p->dr); } } /////////////////// Parcurgerea SDR arborelui by nec void parc_postord (NOD *p) { if(p!=NULL) { parc_postord(p->st); parc_postord(p->dr); printf("\t Nr=%d", p->inf); } } /////////////////// Stergerea arborelui by nec void stergarbore(NOD *p) { if (p!=NULL) { stergarbore(p->st); stergarbore(p->dr); delete p; } } /////////////////// Afisare spatii by nec void spatii(int n) { int i; for(i=0;i<n;i++) putchar(' '); }
16
/////////////////// Afisare arbore by nec void afisare(int n, int f, int k, int vb, int *vn) {int i; spatii(4); if(n) { for(i=1;i<n;i++) { if(vn[i]) putchar(' '); else putchar('|'); spatii(4); } if(f) putchar('|'); else putchar('|'); for(i=0;i<4;i++) putchar('-'); } if(vb) printf("%d\n",k); else printf("...\n"); } /////////////////// Afisare pe nivele by nec void afisare_nivel (NOD *p, int n=0) {static int vn[50],f=1; if(p) { afisare(n,f,p->inf,1,vn); if(p->st || p->dr) { f=1; vn[n+1]=0; afisare_nivel(p->st,n+1); } if(p->st || p->dr) { f=0; vn[n+1]=1; afisare_nivel(p->dr,n+1); } } else afisare(n,f,10,0,vn); } Nchil Ctlin Laborator UPG 17
///////////////// Stergerea unui nod cu doi descendenti by nec int sterg(NOD *&pa) { if(pa->st) return sterg(pa->st); else { NOD *a=pa; int k=a->inf; pa=pa->dr; free(a); return k; } } ///// Stergerea unui nod cu cel putin nu descendent vid by nec void stergerenod(NOD *& p, int k) { NOD *aux; if(p==NULL) printf("\n Nodul %d nu exista ",p->inf); else if(k<p->inf) stergerenod(p->st,k); else if(k>p->inf) stergerenod(p->dr,k); else { aux=p; if(!aux->dr) { p=aux->st; free(aux); } else if(!aux->st) { p=aux->dr; free(aux); } else p->inf=sterg(p->dr); } }
18
/////////////////// Inserare nod by nec void inserare(NOD *&p,int x) {NOD *pnou; if (p==NULL) { pnou=NEW pnou->inf=x; pnou->st=NULL; pnou->dr=NULL; p=pnou; } else if (p->inf>x) inserare(p->st,x); else if (p->inf<x) inserare(p->dr,x); else printf("Elementul deja exista! \n"); } /////////////////// Maximul dintre doua nr by nec int max(int x,int y) {if (x<y) return y; else return x; } /////////////////// Numararea nodurilor arborelui by nec int nrnod(NOD *p) {if(p!=NULL) return 1+nrnod(p->st)+nrnod(p->dr); else return 0; } //////// Determinarea numarului de niveluri ale arborelui by nec int inaltime(NOD *p) {int stanga, dreapta; if(p!=NULL) return 1+max(inaltime(p->st),inaltime(p->dr)); else return 0; } Nchil Ctlin Laborator UPG 19
/////////////////// Programul principal by nec void main() { NOD *rad; int nr,nivel,nrnou,nrsters; clrscr();
///// Crearea si afisarea RSD, SRD, SDR a unui arbore by nec rad=creare(); printf("--------------------------------------------------- \n"); printf("Parcurgere preordine \n"); parc_preord(rad);printf("\n"); printf("Parcurgere inordine \n"); parc_inord(rad);printf("\n"); printf("Parcurgere postordine \n"); parc_postord(rad);printf("\n"); printf("\n"); printf("Afisarea pe niveluri: \n"); afisare_nivel(rad); printf("\n");
///// Stergerea unui nod by nec printf("--------------------------------------------------- \n"); printf("Nodul care se sterge = "); scanf("%d",&nrsters); stergerenod(rad,nrsters); printf("Parcurgere preordine \n"); parc_preord(rad);printf("\n"); printf("Parcurgere inordine \n"); parc_inord(rad);printf("\n"); printf("Parcurgere postordine \n"); parc_postord(rad);printf("\n"); printf("Afisarea pe niveluri: \n"); afisare_nivel(rad);
20
///// Inserarea unui nod by nec printf("--------------------------------------------------- \n"); printf("Numarul de inserat este="); scanf("%d",&nrnou); inserare(rad,nrnou); printf("Parcurgere preordine \n"); parc_preord(rad);printf("\n"); printf("Parcurgere inordine \n"); parc_inord(rad);printf("\n"); printf("Parcurgere postordine \n"); parc_postord(rad);printf("\n"); printf("Afisarea pe niveluri: \n"); afisare_nivel(rad); ///// Nr. noduri & nr. niveluri by nec nr=nrnod(rad); printf("Numarul de noduri este=%d \n",nr); nivel=inaltime(rad); printf("Inaltimea este=%d \n",nivel);
getchar();getchar(); }
21