Documente Academic
Documente Profesional
Documente Cultură
Enunţ:
Scrieti programul C care permite crearea şi vizualizarea unui arbore AVL.
Descrierea algoritmului
Problema constă în inserarea unu nou nod într-un arbore AVL a.î. şi după inserare arborele să
rămână tot AVL.
S D
hs – înălţimea subarborelui stâng
hd – înălţimea subarborelui drept
Pentru a stabili când se impune reechilibrarea şi în ce caz de reechilibrare suntem vom
introduce noţiunea de factor de echilibru a unui arbore AVL înţelegând prin aceasta diferenţa dintre
înălţimea subarborelui său drept şi înălţimea subarborelui său stâng.
Structura arborelui va fii următoarea:
Cele 3 situaţii de inserae într-un arbore AVL referitoare la diferenţa de înălţime dintre
subarborele stâng şi drept se traduc prin intermediul factorului de echilibru al nodului radacina.
Factorul de echilibru al unui nod într-un arbore AVL devine important în realizarea algoritmului
de inserare a unui nod într-un arbore AVL. Acest algoritm se va desfăşura în 3 paşi:
1. se caută în arbore nodul cu cheia de inserat
2. dacă nodul există în arbore se incrementează contorul asociat nodului şi algoritmul se
opreşte, altfel se inserează în locul determinat la pasul 1
3. se merge înapoi pe drumul de căutare între locul de inserat şi nodul radacina restabilind în
mod corespunzător factorul de echilibru pentru toate nodurile de pe acest drum.
Exemplu:
Se consideră arborele:
8
1
4 0
2 6
Cazul I a)
1
4 0
2 6
caracteristicile cazului I a)
După reechilibrare
8
2
1
1 6
0
Cazul I b)
Cazul II a)
p -> 8
1
p1 -> 4 0
2 6 <- p2
Caracteristicile cazului II a)
p1 = p->st;
p2 = p1->dr;
p->ech = -1;
p1->ech = 1;
Arborele se dezechilibrează şi deci se impune reechilibrarea.
Arborele după reechilibrare
8
4
1
2 5
0
Cazul II b)
p -> 8
1
p1 -> 4 0
2 6 <- p2
7
0
6
p2 ->
8
p1 -> 4 <- p
1
2 7 0
Cazul II c)
8
4 <- p1 p1 -> 4 <- p
6 <- p2
p->ech = 0;
p1->ech = 0;
p = p2;
p->ech = 0;
Cele 3 cazuri II a), b), c) le putem uni într-un singur caz: cazul II stânga(S.D.)
Considerăm că p este nodul rădăcină.
p1 = p->st;
p2 = p1->dr;
p->ech = -1;
p1->ech = 1;
p1->dr = p2->st;
p->st = p2->dr;
p2->st = p1;
p2->dr = p;
if(p2->ech==-1)
p->ech = 1;
else p->ech = 0;
if(p2->ech==1)
p->ech = 1;
else p1->ech = 0;
p = p2;
p->ech = 0;
Rezolvare:
Realizaţi programul C care permite crearea şi vizualizarea unui arbore AVL.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
#include <graphics.h>
#include <dos.h>
#define raza 10
#define timp 500
#define spatiu 40
void creare(void);
void inarbore(int, ref *);
void initializare_mod_grafic(void);
void tip(ref, int, int, int, int, int, char *);
void inordine(ref, int, int, int, int, int);
void preordine(ref, int, int, int, int, int);
void postordine(ref, int, int, int, int, int);
void tipt(ref anod, int nivel);
void inordinest(ref rad, int nivel);
void insertechil(int , ref *, int *);
ref Loc(int, ref);/*cauta un nod in arbore*/
ref radacina, r, q;
int x, h,
culoare_fundal=15,/*culoarea de fundal a nodurilor arborelui*/
culoare_scris=1, /*culoarea cu care sunt scrise nodurile arborelui*/
afisare=0;/*pt. cautare*/
void main(void)
{
char op;
radacina = NULL;
do
{
clrscr();
printf("Sa se creeze un arbore binar ordonat si sa se afiseze
grafic\n");
printf(" C. Creare\n");
printf(" N. Insereaza un nod in arbore!\n");
printf(" F. Cauta un nod in arbore\n");
printf(" I. Afisare in mod grafic in inordine\n");
printf(" P. Afisare in mod grafic in preordine\n");
printf(" O. Afisare in mod grafic in postordine\n");
printf(" E. Iesire\n");
printf("Introduceti optiunea: ");
fflush(stdin); op=toupper(getc(stdin));
switch (op)
{
case 'C':
creare();
initializare_mod_grafic();
delay(2000);
settextjustify(1,1);
outtextxy(getmaxx()/2, 10, "Parcurgere in INORDINE" );
setviewport(0,30,getmaxx(), getmaxy(), 1);
inordine(radacina, 0, 0, getmaxx(), getmaxx()/2, raza);
setcolor(WHITE);
outtextxy(getmaxx()/2, getmaxy()-40, "Apasati o tasta pt. a
termina");
fflush(stdin);getch();
closegraph();
break;
case 'N':
printf("Introduceti nodul de inserat: ");
while(scanf("%d", &x)!=1)
{
printf("Introduceti un numar!\n");
fflush(stdin);
printf("Introduceti nodul de inserat: ");
}
h = 0;
insertechil(x, &radacina, &h);
initializare_mod_grafic();
delay(2000);
settextjustify(1,1);
outtextxy(getmaxx()/2, 10, "Inserarea unui nod in arbore");
setviewport(0,30,getmaxx(), getmaxy(), 1);
inordine(radacina, 0, 0, getmaxx(), getmaxx()/2, raza);
setcolor(WHITE);
outtextxy(getmaxx()/2, getmaxy()-40, "Apasati o tasta pt. a
termina");
fflush(stdin);getch();
closegraph();
break;
case 'F':
if(radacina==NULL)
{
printf("Arbore vid!\n");
printf("Apasati o tasta pt. a continua!\n"); getch();
break;
}
afisare = 0;
printf("Introduceti cheia nodului de cautat: ");
while(scanf("%d", &x)==0)
{
printf("Introduceti un intreg!\n");
fflush(stdin);
printf("Introduceti cheia nodului de cautat: ");
}
r = Loc(x, radacina);
if(r == NULL)
printf("Nodul nu exista in arbore!\n");
else
{
afisare = 1;
initializare_mod_grafic();
delay(2000);
settextjustify(1,1);
outtextxy(getmaxx()/2, 10, "Cautarea unui nod in
arbore");
setviewport(0,30,getmaxx(), getmaxy(), 1);
inordine(radacina, 0, 0, getmaxx(), getmaxx()/2, raza);
setcolor(WHITE);
outtextxy(getmaxx()/2, getmaxy()-40,
"Nodul a fost gasit in arbore");
fflush(stdin);getch();
closegraph();
}
break;
case 'I':
if(radacina==NULL)
{
printf("Arborele este vid\n");
printf("Apasati o tasta pt. a continua\n");getch();
}
else
{
initializare_mod_grafic();
delay(2000);
settextjustify(1,1);
outtextxy(getmaxx()/2, 10, "Parcurgere in INORDINE" );
setviewport(0,30,getmaxx(), getmaxy(), 1);
inordine(radacina, 0, 0, getmaxx(), getmaxx()/2, raza);
setcolor(WHITE);
outtextxy(getmaxx()/2, getmaxy()-40, "Apasati o tasta pt.
a termina");
fflush(stdin);getch();
closegraph();
}
break;
case 'P':
if(radacina==NULL)
{
printf("Arborele este vid\n");
printf("Apasati o tasta pt. a continua\n");getch();
}
else
{
initializare_mod_grafic();
delay(2000);
settextjustify(1,1);
outtextxy(getmaxx()/2, 10, "Parcurgere in PREORDINE" );
setviewport(0,30,getmaxx(), getmaxy(), 1);
preordine(radacina, 0, 0, getmaxx(), getmaxx()/2, raza);
setcolor(WHITE);
outtextxy(getmaxx()/2, getmaxy()-40, "Apasati o tasta pt.
a termina.");
fflush(stdin);getch();
closegraph();
}
break;
case 'O':
if(radacina==NULL)
{
printf("Arborele este vid\n");
printf("Apasati o tasta pt. a continua\n");getch();
}
else
{
initializare_mod_grafic();
delay(2000);
settextjustify(1,1);
outtextxy(getmaxx()/2, 10, "Parcurgere in POSTORDINE" );
setviewport(0,30,getmaxx(), getmaxy(), 1);
postordine(radacina, 0, 0, getmaxx(), getmaxx()/2, raza);
setcolor(WHITE);
outtextxy(getmaxx()/2, getmaxy()-40, "Apasati o tasta pt.
a termina.");
fflush(stdin);getch();
closegraph();
}
break;
case 'E':
break;
default:
printf("\nOptiune invalida !\nApasati o tasta!\n");
getch();
break;
}
}
while(op!='E');
}/*main*/
void creare(void)
{
radacina = NULL;
printf("Introduceti nodurile(0 pt. a termina): ");
while(scanf("%d", &x)!=1)
{
printf("Introduceti un numar!");
fflush(stdin);
}
while(x!=0)
{
h = 0;
insertechil(x, &radacina, &h);
printf("Introduceti nodurile(0 pt. a termina): ");
while(scanf("%d", &x)!=1)
{
printf("Introduceti un numar!\n");
fflush(stdin);
printf("Introduceti nodurile(0 pt. a termina): ");
}
}
}/*creare*/
void inordine(ref rad, int nivel, int x1, int x2, int c1, int c2)
{
static char s[10];
if(rad!=NULL)
{
inordine(rad->st, nivel+1, x1, (x1+x2)/2, (x1+x2)/2,
nivel*spatiu+raza);
tip(rad, nivel, x1, x2, c1, c2, s);
inordine(rad->dr, nivel+1, (x1+x2)/2, x2, (x1+x2)/2,
nivel*spatiu+raza);
}
}/*inordine*/
void preordine(ref rad, int nivel, int x1, int x2, int c1, int c2)
{
static char s[10];
if(rad!=NULL)
{
preordine(rad->st, nivel+1, x1, (x1+x2)/2, (x1+x2)/2,
nivel*spatiu+raza);
preordine(rad->dr, nivel+1, (x1+x2)/2, x2, (x1+x2)/2,
nivel*spatiu+raza);
tip(rad, nivel, x1, x2, c1, c2, s);
}
}/*preordine*/
void postordine(ref rad, int nivel, int x1, int x2, int c1, int c2)
{
static char s[10];
if(rad!=NULL)
{
postordine(rad->dr, nivel+1, (x1+x2)/2, x2, (x1+x2)/2,
nivel*spatiu+raza);
tip(rad, nivel, x1, x2, c1, c2, s);
postordine(rad->st, nivel+1, x1, (x1+x2)/2, (x1+x2)/2,
nivel*spatiu+raza);
}
}/*postordine*/
void tip(ref anod, int nivel, int x1, int x2, int c1, int c2, char *s)
{
if(afisare==1 && anod==r)
{
culoare_scris=BLUE;
culoare_fundal=RED;
}
else
{
culoare_scris=1;/*albastru*/
culoare_fundal=15;/*alb*/
}
setcolor(15);
line((x1+x2)/2, nivel*spatiu+raza, c1,c2+textheight("1")/2);
setfillstyle(SOLID_FILL, culoare_fundal);
fillellipse((x1+x2)/2, nivel*spatiu+raza, raza, raza);
setcolor(culoare_scris);/*albastru*/
sprintf(s, "%d", anod->cheie);
outtextxy((x1+x2)/2, nivel*spatiu+raza, s);
delay(timp);
r = NULL;
}/*tiparire grafica*/