Documente Academic
Documente Profesional
Documente Cultură
Laborator 11 – Cel mai scurt drum intre doua noduri ale unui graf………………………………………….66
Modul grafic presupune că ecranul este format din “puncte luminoase”(pixeli). Numărul
acestora depinde de adaptorul grafic şi se numeşte rezoluţie. O rezoluţie este cu atât mai bună
cu cât este mai mare.
Pentru gestiunea ecranului în mod grafic se pot utiliza peste 60 de funcţii din biblioteca
sistemului. Aceste funcţii au prototipul în fişierul graphics.h.
Modul grafic se setează cu ajutorul funcţiei initgraph. Apelul funcţiei cere trei parametrii. Primul
parametru va specifica driverul grafic folosit, al doilea parametru va specifica modul grafic, iar cel de-al
treilea parametru, calea către locul în care funcţia initgraph va căuta driverul grafic.
Aceste operaţii le vom include într-o funcţie pe care o vom numi InitializareModGrafic
Gestiunea culorilor
Starea ecranului
În mod grafic, ecranul se compune din n*m puncte luminoase(pixeli). Aceasta înseamnă
că pe ecran se pot afişa m linii a n pixeli fiecare.
(x, y)
void tip(ref anod, int nivel, int x1, int x2, int c1, int c2, char *s)
{
setcolor(15);
line((x1+x2)/2, nivel*spatiu+raza, c1,c2+textheight("1")/2);
fillellipse((x1+x2)/2, nivel*spatiu+raza, raza, raza);
setcolor(1);/*albastru*/
sprintf(s, "%d", anod->cheie);
outtextxy((x1+x2)/2, nivel*spatiu+raza, s);
delay(timp);
}/*tiparire grafica*/
Tema 1: Scrieti programul C, care permite crearea si vizualizarea in mod grafic a unui arbore binar
ordonat dat cu n noduri.
Codul sursa:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<ctype.h>
#include<math.h>
#include<graphics.h>
#include<dos.h>
ref radacina;
int N,x;
char op;
void Init_Mod_Grafic(void)
{
int gdriver=DETECT,gmode,er;
initgraph(&gdriver,&gmode,ADR);
er=graphresult();
if(er!=grOk)
{
printf("Eroare initializare mod grafic!");
getch();
}
}//initializare mod grafic
void Inarbore(ref *t,int x)
{
if((*t)==NULL)
{
(*t)=(ref)malloc(sizeof(Tnod));
(*t)->st=NULL;
(*t)->dr=NULL;
(*t)->cheie=x;
}
else
if(x<(*t)->cheie)
Inarbore(&((*t)->st),x);
else
Inarbore(&((*t)->dr),x);
}//Inarbore
void Creare(void)
{
radacina=NULL;
printf("Adaugi?(D/N):");
fflush(stdin);scanf("%c",&op);op=toupper(op);
while(op=='D')
{
printf("Cheia= ");scanf("%d",&x);
Inarbore(&radacina,x);
printf("Mai adaugi?(D/N):");
fflush(stdin);scanf("%c",&op);op=toupper(op);
}
}//Creare
void Adaugare(void)
{
if(radacina==NULL)
printf("Arbore vid! Trebuie Creat.\n");
else
{
printf("Cheia= ");scanf("%d",&x);
Inarbore(&radacina,x);
}
}//Adaugare
void Sageata(int Ax,int Ay,int Bx,int By)
{
double B1x,B1y,B2x,B2y,tempxA,tempyA,tempxB,tempyB;
double alpha,alpha1,alpha2;
//masura unghiului segmentului de baza
if(Bx-Ax!=0)
{
alpha=1.0*(Ay-By)/(Bx-Ax);
alpha=atan((double)alpha);
tempxA=Ax+((Bx-Ax>=0)?1:-1)*raza*cos(alpha);
tempyA=Ay-((Bx-Ax>=0)?1:-1)*raza*sin(alpha);
tempxB=Bx-((Bx-Ax>=0)?1:-1)*raza*cos(alpha);
tempyB=By+((Bx-Ax>=0)?1:-1)*raza*sin(alpha);
//se deseneaza segmentul de baza
line (tempxA,tempyA,tempxB,tempyB);
//determinarea masurii unghiurilor segmentelor
//ce compun varful sagetii
alpha1=1.0*(((Bx-Ax<0)?0:PI)-alpha+PI/6);
alpha2=1.0*(((Bx-Ax<0)?0:PI)-alpha-PI/6);
//se determina coordonatele capetelor segmentelor
//ce compun varful sagetii
B1x=tempxB+cos(alpha1)*marimeSageata;
B1y=tempyB+sin(alpha1)*marimeSageata;
B2x=tempxB+cos(alpha2)*marimeSageata;
B2y=tempyB+sin(alpha2)*marimeSageata;
//se deseneaza varful sagetii
line(tempxB,tempyB,B1x,B1y);
line(tempxB,tempyB,B2x,B2y);
}
}//sageata
void tip(ref anod,int nivel,int x1,int x2,int c1,int c2,char *s)
{
setcolor(WHITE);
Sageata(c1,c2,(x1+x2)/2,nivel*spatiu+raza);
fillellipse((x1+x2)/2,nivel*spatiu+raza,raza,raza);
setcolor(BLACK);
settextstyle(1,0,2);
sprintf(s,"%d",anod->cheie);
outtextxy((x1+x2)/2,nivel*spatiu+raza,s);
delay(intarziere);
}//tiparire grafic
void Inordine(ref rad,int nivel,int x1,int x2,int c1,int c2)
{
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 grafica
void Preordine(ref rad,int nivel,int x1,int x2,int c1,int c2)
{
char s[10];
if(rad!=NULL)
{
tip(rad,nivel,x1,x2,c1,c2,s);
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);
}
}//preordine grafica
void Postordine(ref rad,int nivel,int x1,int x2,int c1,int c2)
{
char s[10];
if(rad!=NULL)
{
Postordine(rad->st,nivel+1,x1,(x1+x2)/2,
(x1+x2)/2,nivel*spatiu+raza);
Postordine(rad->dr,nivel+1,(x1+x2)/2,x2,
(x1+x2)/2,nivel*spatiu+raza);
tip(rad,nivel,x1,x2,c1,c2,s);
}//postordine grafica
ref Loc(int x,ref t)
{
int gasit=0;
while((gasit==0)&&(t!=NULL))
if(x<t->cheie)
t=t->st;
else
if(x>t->cheie)
t=t->dr;
else gasit=1;
return t;
}//Loc
void main (void)
{
int N;
char op;
do
{
clrscr();
printf("Crearea Arborilor Binari Ordonati\n\n");
printf("C.Creare\n");
printf("A.Adaugare\n");
printf("I.Vizualizare grafica in inordine \n");
printf("P.Vizualizare grafica in preordine \n");
printf("T.Vizualizare grafica in postordine \n");
printf("S.Cautare\n");
printf("E.iesire\n\n");
printf("Introduceti optiunea: "); scanf("%c",&op);op=toupper(op);
switch(op)
{
case 'C': clrscr();
Creare();
break;
case 'A': clrscr();
Adaugare();
break;
case 'I': Init_Mod_Grafic();
cleardevice();
delay(2000);
settextjustify(1,1);
if(radacina!=NULL)
{
outtextxy(getmaxx()/2,25,
"Arborele_In_Inordine");
setviewport(0,60,getmaxx(),getmaxy(),1);
Inordine(radacina,0,0,getmaxx(),
getmaxx()/2,raza);
setcolor(WHITE);
}
else
outtextxy(getmaxx()/2, 25, "Arbore_Vid" );
outtextxy(getmaxx()/2,getmaxy()-100, "Tastati_Enter");
getch();
closegraph();
break;
case 'P': Init_Mod_Grafic();
cleardevice();
delay(2000);
settextjustify(1,1);
if(radacina!=NULL)
{
outtextxy(getmaxx()/2,25,
"Arborele_In_Preordine"); setviewport(0,60,getmaxx(),getmaxy(),1);
Preordine(radacina,0,0,getmaxx(),
getmaxx()/2,raza);
setcolor(WHITE);
}
else
outtextxy(getmaxx()/2, 25, "Arbore_Vid");
outtextxy(getmaxx()/2, getmaxy()-100, "Tastati_Enter");
getch();
closegraph();
break;
case 'T': Init_Mod_Grafic();
cleardevice();
delay(2000);
settextjustify(1,1);
if(radacina!=NULL)
{
outtextxy(getmaxx()/2,25,
"Arborele_In_Postordine");
setviewport(0,60,getmaxx(),getmaxy(),1);
Postordine(radacina,0,0,getmaxx(),
getmaxx()/2,raza);
setcolor(WHITE);
}
else
outtextxy(getmaxx()/2,25,"Arbore_Vid");
outtextxy(getmaxx()/2,getmaxy()-100, "Tastati_Enter");
getch();
closegraph();
break;
case 'S': clrscr(); if(radacina==NULL)
printf("Arbore vid!\n");
else
{
printf("Cheia nodului cautat: ");
scanf("%d",&x);
if(Loc(x,radacina)==NULL)
printf("Nodul nu s-a gasit!\n");
else
{
printf("S-a gasit nodul cu cheia");
printf(" %d la adresa %d\n",x,
Loc(x,radacina));
}
}
break;
case 'E': break;
default : printf("Optiune gresita!\n");
break;
}
printf("Tastati Enter\n");
fflush(stdin);
getch();
}
while(op!='E');
}
OBSERVAŢII
Arbori AVL
Dacă se doreşte să organizăm o colecţie de date ca o structură de arbore de căutare, şi
întrucât ştim că operaţiile de inserare şi de suprimare a unui nod dintr-un arbore binar ordonat
si perfect echilibrat va deveni foarte dificilă atunci când dorim sa pastrăm structura, Adelson
Velskii şi Landish au propus o structură mai puţin restrictivă şi anume structura de arbore binar
ordonat şi echilibrat (după înălţime).
Un arbore binar se zice că este echilibrat şi înţelegem după înălţime dacă diferenţa
dintre înălţimea celor doi subarbori este cel mult 1 pentru fiecare nod al arborelui.
Un arbore echilibrat după înălţime se mai numeşte si arbore AVL după numele celor
care i-au definit structura.
1. hs<hd 1) hs=hd
2. hs=hd 2) hs>hd
3. hs>hd 3) se dezechilibrează, se impune reechilibrarea
Tema 1: