#include <iostream>
#include <winbgim.h>
#include <cmath>
#define ARRAYSIZE 10000
using namespace std;
/*ALGORITMI ZA MANIPULACIJU SA STABLIMA*/
/*REALIZACIJA PREKO POLJA*/
struct tdata{
char label[20];
int firstChild;
int nextSibling;
};
struct tree{
tdata data[ARRAYSIZE];
int first;
};
void createChild(int x, tree *t){
cout << "Uneiste ime djeteta: ";
cin >> t->data[x].label;
t->data[x].firstChild = -1;
t->data[x].nextSibling = -1;
}
int Root(tree *t){
return t->first;
}
tree* Init(int x, tree *t){
t = new tree;
t->first = x;
createChild(x,t);
for(int i=0; i<ARRAYSIZE; i++){
if(i==x) continue;
strcpy(t->data[i].label,"");
t->data[i].firstChild = -1;
t->data[i].nextSibling = -1;
}
return t;
}
char* Label(int n, tree *t){
return t->data[n].label;
}
void ChangeLabel(char *x, int n, tree *t){
strcpy(t->data[n].label,x);
}
void Create(int x, int n, tree *t){
if(t->data[n].firstChild==-1){
t->data[n].firstChild = x;
createChild(x,t);
cout << "Djete " << t->data[x].label << " je pridruzeno roditelju " << t->data[n].label << endl;
return;
}
int brother = t->data[n].firstChild;
while(true)
if(t->data[brother].nextSibling==-1)
break;
else
brother = t->data[brother].nextSibling;
t->data[brother].nextSibling = x;
createChild(x,t);
cout << "Djete " << t->data[x].label << " je pridruzeno roditelju " << t->data[n].label << endl;
}
int Parent(int n, tree *t){
if(t->first==n)
return -1;
else
for(int i=0; i<ARRAYSIZE; i++)
if(t->data[i].firstChild==n)
return i;
else if(t->data[i].nextSibling==n)
return Parent(i,t);
return -1;
}
int FirstChild(int n, tree *t){
return t->data[n].firstChild;
}
int NextSibling(int n, tree *t){
return t->data[n].nextSibling;
}
void Delete(int n, tree *t, bool prvi=true){
if(t->data[n].firstChild != -1){
Delete(t->data[n].firstChild,t, false);
t->data[n].firstChild = -1;
strcpy(t->data[n].label,"");
}
if(t->data[n].nextSibling != -1){
if(prvi){ // ukoliko je prvi krug
if(t->data[Parent(n,t)].firstChild==n){ //ukoliko sam ja prvo djete, onda je moj brat sljedece djete
t->data[Parent(n,t)].firstChild=t->data[n].nextSibling;
t->data[n].nextSibling = -1;
strcpy(t->data[n].label,"");
} else {//Inace pronađi ko ima pokazivač na mene
int brother = t->data[Parent(n,t)].firstChild; //Ovo je prvo djete mojeg roditelja
while(true)
if(t->data[brother].nextSibling==n)
break;
else
brother = t->data[brother].nextSibling;
t->data[brother].nextSibling = t->data[n].nextSibling;
t->data[n].nextSibling = -1;
strcpy(t->data[n].label,"");
}
} else {
Delete(t->data[n].nextSibling,t, false);
t->data[n].nextSibling = -1;
strcpy(t->data[n].label,"");
}
}
if(t->data[n].firstChild==t->data[n].nextSibling)
strcpy(t->data[n].label,"");
}
/*ALGORITMI OBILASKA STABLA*/
void Preorder(tree *t, int n){
if(n==-1) return;
cout << t->data[n].label << endl;
Preorder(t, FirstChild(n, t));
Preorder(t, NextSibling(n, t));
}
void Inorder(tree *t, int n){
if(n==-1)return;
Inorder(t, FirstChild(n, t));
cout << t->data[n].label << endl;
Inorder(t, NextSibling(n, t));
}
void Postorder(tree *t, int n){
if(n==-1)return;
Preorder(t, FirstChild(n, t));
Preorder(t, NextSibling(n, t));
cout << t->data[n].label << endl;
}
/*ALGORITAM ZA CRTANJE STABLA*/
/*Napomena:
-algoritam za iscrtavanje koji je naveden u ovom primjeru je prvi algoritam kojega sam napisao za ovu svrhu, te kao takav je dosta ne strukturiran. Ukoliko želite bolje strukturirani kod, pogledajte kod za iscrtavanje binarnog stabla
*/
int indeks_prepisa, num;
void pomCrtaj(tree *t, int m[][5]){
/*Iscrtavanje sadržaja na ekran prema prosljeđenim parametrima*/
int gdrive = 9;
int gmode = 2;
initgraph(&gdrive, &gmode, "");
setbkcolor(WHITE);
setcolor(BLACK);
cleardevice();
for(int i=0; i<num; i++){
circle(m[i][1], m[i][2], 10);
if(m[i][4])line(m[i][1], m[i][2], m[i][3], m[i][4]);
outtextxy(m[i][1]-5,m[i][2]-7,Label(m[i][0],t));
}
getch();
closegraph();
}
void Prepisi(tree *t, int n, int p[]){
/*Prepis binarnog stabla u polje*/
if(n==-1) return;
Prepisi(t, FirstChild(n,t),p);
if(strcmp(t->data[n].label,"")) p[indeks_prepisa++] = n;
Prepisi(t, NextSibling(n,t),p);
}
void Prebroji(tree *t, int n){
if(n==-1) return;
Prebroji(t, FirstChild(n,t));
if(strcmp(t->data[n].label,"")) num++;
Prebroji(t, NextSibling(n,t));
}
void Poravnaj(int m[][5]){
/*Provjera koeficijenata smjera, ukoliko susjedi imaju isti koeficijent smjera
to znači da se nalaze na istom pravcu i to treba promjeniti*/
for(int i=1; i<num-1; i++){
float k1 = ((m[i][4]-m[i][2])*1.00)/(m[i][3]-m[i][1]);
float k2 = ((m[i+1][4]-m[i+1][2])*1.00)/(m[i+1][3]-m[i+1][1]);
//cout << endl << k1 << "\t" << k2 << endl << endl;
if(k1==k2){
int _x = m[i+1][1], _y = m[i+1][2];
int n_x = _x+25, n_y = _y+25;
m[i+1][1] = n_x;
m[i+1][2] = n_y;
for(int j=0; j<num; j++)
if(m[j][3]==_x && m[j][4]==_y ){
m[j][3]= n_x;
m[j][4]= n_y;
}
}
}
/*Provjeri udaljenost dali su preblizu, ako da udalji ih*/
for(int i=1; i<num-1; i++){
float udaljenost = sqrt((m[i][3]-m[i][1])*(m[i][3]-m[i][1])+(m[i][4]-m[i][2])*(m[i][4]-m[i][2]));
if(udaljenost<60){
int _x = m[i][1], _y = m[i][2];
int n_x = _x+75, n_y = _y+75;
m[i][1] = n_x;
m[i][2] = n_y;
for(int j=0; j<num; j++)
if(m[j][3]==_x && m[j][4]==_y ){
m[j][3]= n_x;
m[j][4]= n_y;
}
}
}
}
void Crtaj(tree *t){
num = 0;
Prebroji(t, Root(t));
int p[num];
int m[num][5];
indeks_prepisa=0;
Prepisi(t,Root(t),p); //prepisuje bin. stablo u polje
/*Izračunaj x,y koordinate za krug i početak linije*/
for(int i=0; i<num; i++){
m[i][0] = p[i]; //vrjednost
m[i][1] = 50+20*m[i][0]; //x - krug i crta
m[i][2] = num*50-i*50; //y - krug i crta
}
/*Izračunaj x,y za kraj linije*/
for(int i=0; i<num; i++){
int j;
int par = Parent(m[i][0],t);
if (par==-1){//Ukoliko nema linije početak i kraj su isti
m[i][3] = m[i][1]; //x - crta kraj
m[i][4] = m[i][2]; //y - crta kraj
continue;
}
for(j=0; j<num; j++)
if(par==m[j][0])
break;
m[i][3] = m[j][1];
m[i][4] = m[j][2];
}
Poravnaj(m); // presloži sadržaj
/*Ispis tablice stanja*/
cout << "L\tV\tX\tY\tX\tY\tK\tU\n";
cout << endl;
for(int i=0; i<num; i++){
cout << Label(m[i][0],t) << "\t";
cout << m[i][0] << "\t"
<< m[i][1] << "\t" << m[i][2] << "\t"
<< m[i][3] << "\t" << m[i][4] << "\t";
if((m[i][3]-m[i][1])!=0){
float rez = ((m[i][4]-m[i][2])*1.00)/(m[i][3]-m[i][1]);
float rez2 = sqrt((m[i][3]-m[i][1])*(m[i][3]-m[i][1])+(m[i][4]-m[i][2])*(m[i][4]-m[i][2]));
cout << rez << "\t" << rez2;
}
cout << endl;
}
pomCrtaj(t,m); //Poziv crtanja
}