Differenze tra le versioni di "Algoritmi e strutture dati/Progetti/Rettangoli/Stesura I"
m (Riportata alla revisione precedente da Yoruno) |
|
(3 versioni intermedie di 3 utenti non mostrate) | |
(Nessuna differenza)
|
Versione attuale delle 13:07, 8 mar 2006
#include <stdio.h> #include <stdlib.h> /* definizione dei tipi */ typedef enum{red, black} color; struct rbapple { int xx; int yy; color co; char touch; struct rbapple *left; struct rbapple *right; struct rbapple *parent; }; /* struttura di ogni nodo dell'albero dei punti*/" typedef struct rbapple rbapple; struct rbalbero { rbapple *root; rbapple *nul; }; /*struttura contenente i puntatori alla radice e alla sentinella" dell'albero dei punti*/" struct rbnode { color co ; int a; int b; int c; int d; char campo; struct rbnode *sinistra; struct rbnode *destra; struct rbnode *genitore; }; /*struttura di ogni nodo dell'albero dei rettangoli*/" typedef struct rbnode rbnode; struct rbtree { rbnode *root; rbnode *nil; }; /*struttura contenente i puntatori alla radice e alla sentinella" dell'albero dei rettangoli*/" typedef struct rbalbero rbalbero; typedef struct rbtree rbtree; /* variabili globali */" rbtree *spazio=NULL; /*puntatore all'albero dei rettangoli*/ rbtree *blocco=NULL;/*puntatore all'albero contennte i rettangoli facenti parte di un blocco*/" rbalbero *foglio=NULL;/*puntatore all'albero dei punti*/ rbalbero *niubbio=NULL;/*puntatore all'albero contenente i punti che vanno rimossi*/" int par1=0, par2=0, par3=0, par4=0, /* variabili di input*/" perimetro= 0, max_x=0, /*dimensione massima dell'ascissa del piano*/ max_y=0; /*dimensione massima dell'ordinata del piano*/ char com; /*parametro di scelta*/ /* prototipi di FUNZIONI E PROCEDURE" */ /* procedure principali */ void procedura_perimetro(void); void procedura_blocco(void); void rbdelete(rbalbero *tree, rbapple *q); void scorri_albero_rettangoli (rbtree *perno, rbnode *buster, rbalbero *joshua , rbapple *corda,int x, int y,rbalbero *elimina); void elimina_interni_foglio(rbalbero *tree, rbapple *q,rbnode *helper, int x, int y ,rbalbero *elimina); void scorri_albero_punti(rbalbero *sanato, rbapple *helper, rbtree *f, rbnode *element, rbalbero *elimina); void ruotaadestra(rbalbero *andtrea , rbapple *giovanni); void inizializzacampo(rbnode *pino, rbnode *peppe); void fixup(rbalbero *tree, rbapple *x); void elimina_albero_supporto(rbalbero *sanato, rbapple *helper); void elimina_puntini(rbalbero *sanato, rbapple *helper, rbalbero *albero_punti); void inserisci_foglio(rbalbero *carmencita, int yukapan, int turu); void canc_albero(rbapple *plastica, rbapple *impertinente); void costruisci_foglio(rbnode *attacca, rbnode *lattina, rbalbero *the); void inserisci_blocco(rbtree *dd, int c, int z, int vv, int sc); void creablocco(rbnode *at, rbnode *ds, rbtree *pc, rbtree *os, int bin, int ffe, int cut, int fre); void ruotaasinistra(rbalbero *pat, rbapple *emilia); void inserisci_punto (rbalbero *carmen, int lardo, int palino); void elimina_tutto_l_albero(rbnode *uno, rbnode *due); void rightrotate(rbtree *ssa , rbnode *eew); void leftrotate(rbtree *gix, rbnode *giz); void inserisci_in_albero(rbtree *csi, int x , int y, int z, int u); void installarettangolo1(rbtree *doo, int you, int foo, int sedd, int degr); void search_block(rbnode *fab, rbnode *anna, rbtree *lobot, char drea, int cse, int cpi); /* funzioni */ int perimetroeblocco(rbalbero *foglio, int peri, char p_o_b); int ilpuntoeinterno(rbnode *p,int x, int y); rbapple *treesucc(rbalbero *tree, rbapple *q); rbapple *treemin(rbapple *p, rbalbero *tree); rbapple *minimo_foglio(rbapple *paolo, rbapple *piero); rbapple *trova_nodofoglio(rbalbero *eustachio, int adalberto , int paola); rbapple *crea_apple(rbalbero *lindo, int cccp, int ostro); rbapple *inserisci_apple(rbalbero *orin, int elio, int samaga); rbalbero *costruisci_blocco(rbtree *star, rbtree *stor, rbalbero *bull, int e, int f,char g);" rbalbero *crea_rbalbero(int gino); rbtree *crea_rbtree(void); rbtree *crea_spazio(rbtree *der, int ddr, int fviva); rbnode *cercanodino(rbtree *nonnot, int defr, int wwe, int t342, int dds); rbnode *assegna_rbnode(rbtree *eew, int, int, int, int); rbnode *metti_un_elemento(rbtree *lls, int d, int f, int r, int t); /* implementazione delle FUNZIONI e PROCEDURE" */ rbtree *crea_spazio(rbtree *spazio, int x, int y) /* questa procedura controlla che non sia già presente uno spazio e ne crea uno di dimensioni x y; nel caso in cui ci sia già uno spazio, lo cancella e, solo dopo crea quello richiesto. Nel primo caso il tempo è O(1), nel secondo dipende dalla funzione che elimina l' albero precedente. */ { max_x=x; max_y=y; if(!spazio) { if (!(spazio = crea_rbtree())) exit(-2); } else { elimina_tutto_l_albero(spazio->root, spazio->nil); free(spazio); if (!(spazio = crea_rbtree())) exit(-2); } return spazio; } void procedura_blocco(void) /* questa procedura racchiude tutte le operazioni da compiere per calcolare e stampare a video la descrizione del contorno del blocco */ { if(foglio != NULL) {" canc_albero(foglio->root, foglio->nul);" free(foglio);" foglio = NULL;" }" if(!(par1 >= 0 && par2 >= 0 && par1 <=max_x && par2<=max_y))" {" printf(""b -1"");" }" else" {" foglio = costruisci_blocco(spazio, blocco, foglio, par1, par2,'b');" if(foglio != NULL)" {" if (!(niubbio=crea_rbalbero(1)))" exit(-2);" scorri_albero_punti(foglio, foglio->root, spazio, spazio->root, niubbio);" elimina_puntini(niubbio, niubbio->root,foglio);" elimina_albero_supporto(niubbio, niubbio->root);" free(niubbio->nul);" free(niubbio);" perimetro = perimetroeblocco(foglio, perimetro, 'b');" }" }" } void elimina_tutto_l_albero(rbnode *ghigo, rbnode *nil) /* questa procedura elimina tutto l'albero passatole in input. tempo @(n), essendo n i nodi dell'albero da cancellare. */ { if (ghigo->destra!=nil)" elimina_tutto_l_albero(ghigo->destra,nil);" if (ghigo->sinistra!=nil)" elimina_tutto_l_albero(ghigo->sinistra, nil);" ghigo->genitore = nil;" free (ghigo);" } rbtree *crea_rbtree(void) /* questa funzione crea e inizializza la radice e la sentinella di un albero e ne restituisce il puntatore. tempo @(1) */ { rbtree *tree = malloc(sizeof(rbtree)); if(!tree) return NULL;" if(!(tree->root = malloc(sizeof(rbnode)))) return NULL;" tree->nil = tree->root; tree->nil->sinistra = tree->nil->destra = tree->nil->genitore = tree->nil; tree->nil->co = black; return tree; } void elimina_puntini(rbalbero *sanato, rbapple *helper, rbalbero *albero_punti) /* questa procedura elimina i punti interni del blocco, che abbiamo precedentemente inserito in un albero. tempo O(n), essendo n i nodi da cancellare. (va anlizzata a parte la procedura che effettivamente elimina i nodi) */ {" rbapple *kiss; if (helper->left!=sanato->nul) elimina_puntini(sanato, helper->left, albero_punti);" kiss = trova_nodofoglio(albero_punti, helper->xx, helper->yy);" if (kiss)" rbdelete(albero_punti, kiss);" if (helper->right!=sanato->nul) elimina_puntini(sanato, helper->right,albero_punti);" } void elimina_albero_supporto(rbalbero *sanato, rbapple *helper) /* questa procedura distrugge completamente un albero di tipo rbalbero. tempo @(n), essendo n i nodi dell'albero. */ { rbapple *kiss; if (helper->left!=sanato->nul) elimina_albero_supporto(sanato, helper->left);" if (helper->right!=sanato->nul) elimina_albero_supporto(sanato, helper->right);" free(helper);" } void installarettangolo1(rbtree *spazio, int a, int b, int c, int d) /* questa procedura inserisce un rettangolo nell'albero in input. tempo O(log n) dovuto alla ricerca nell'albero e all'insrimento */ { rbnode *maya =NULL; if((a < c)&&(a >=0)&&(b < d)&&(b >= 0)&&(c <= max_x)&&(d <=max_y)&&(c >=0)&&(d>=0)) { maya = cercanodino(spazio, a, b, c, d); if(maya == NULL) { inserisci_in_albero(spazio, a, b, c, d); } } } void inserisci_in_albero(rbtree* spazio, int a, int b, int c, int d) /* questa procedura inserisce un nodo in un'albero rb e ne ripristina le proprietà. tempo @(log n) dovuto alla ricerca dello spazio nell'albero */ { rbnode *fatur = metti_un_elemento(spazio, a, b, c, d);" rbnode *iron = NULL; if (fatur != NULL){ while(fatur != spazio->root && fatur->genitore->c == red) { if(fatur->genitore == fatur->genitore->genitore->sinistra) { iron = fatur->genitore->genitore->destra; if(iron->co == red) { fatur->genitore->co = black; iron->co = black; fatur->genitore->genitore->co = red; fatur= fatur->genitore->genitore; } else { if(fatur == fatur->genitore->destra) { fatur = fatur->genitore;" leftrotate(spazio, fatur);" } fatur->genitore->co = black; fatur->genitore->genitore->co = red; rightrotate(spazio, fatur->genitore->genitore); } } else { iron = fatur->genitore->genitore->sinistra; if(iron->co == red) { fatur->genitore->co = black; iron->co = black; fatur->genitore->genitore->co = red; fatur = fatur->genitore->genitore; } else { if(fatur == fatur->genitore->sinistra) { fatur = fatur->genitore;" rightrotate(spazio, fatur);" } fatur->genitore->co = black; fatur->genitore->genitore->co = red; leftrotate(spazio, fatur->genitore->genitore); } } } spazio->root->co = black;} } rbnode *metti_un_elemento(rbtree *spazio, int a, int b, int c, int d) /* questa procedura inserisce un elemento in un albero rb, come se si trattasse di un albero binario di ricerca. tempo @(log n) limitato superiormente dal fatto che l'albero è bilanciato, in quanto rb. */ { char pink; rbnode *bruce = spazio->root; rbnode *purple = spazio->nil; while(bruce != spazio->nil) { purple = bruce; if(a == purple->a && b == purple->b && c == purple->c && d == purple->d) return NULL; else if(a >= purple->a && b >= purple->b && c <= purple->c && d <= purple->d) return NULL; else if (a < purple->a) pink = 'n'; else if(a > purple->a) pink = 'y'; else if(a == purple->a && b < purple->b) pink = 'n'; else if(a == purple->a && b > purple->b) pink = 'y'; else if(a == purple->a && b == purple->b && c < purple->c) pink = 'n'; else if(a == purple->a && b == purple->b && c > purple->c) pink = 'y'; else if(a == purple->a && b == purple->b && c == purple->c && d <= purple->d) pink= 'n'; else pink = 'y'; if (pink == 'n') bruce =purple->sinistra; else bruce=purple->destra; } bruce = assegna_rbnode(spazio, a, b, c, d); bruce->genitore = purple; if(purple == spazio->nil) spazio->root = bruce; else if(a < purple->a) purple->sinistra = bruce; else if(a > purple->a) purple->destra = bruce; else if(a == purple->a && b < purple->b) purple->sinistra = bruce; else if(a == purple->a && b > purple->b) purple->destra = bruce; else if(a == purple->a && b == purple->b && c < purple->c) purple->sinistra = bruce; else if(a == purple->a && b == purple->b && c > purple->c) purple->destra = bruce; else if(a == purple->a && b == purple->b && c == purple->c && d <= purple->d) purple->sinistra = bruce; else purple->destra = bruce; return bruce; } rbnode *assegna_rbnode(rbtree *spazio, int a, int b, int c, int d) /* questa procedura alloca spazio per un nodo di tipo rbtree. In caso no riuscisse ad allocare spazio in memoria esce dal programma e restituisce un codice di errore. tempo @(1) */ { rbnode *figaro = NULL; if (!(figaro = malloc(sizeof(rbnode)))) exit(-2); figaro->campo='n'; figaro->co=red; figaro->a=a; figaro->b=b; figaro->c=c; figaro->d=d; figaro->destra = spazio->nil; figaro->sinistra = spazio->nil; figaro->genitore=spazio->nil; return figaro; } void leftrotate(rbtree* spazio, rbnode* indotto) /* questa procedura produce una rotazione necessaria al ripristino delle proprietà dell'alberorb. tempo @(1) */ { rbnode *y = indotto->destra; indotto->destra = y->sinistra; if (y->sinistra != spazio->nil) y->sinistra->genitore = indotto;" y->genitore = indotto->genitore;" if (indotto->genitore==spazio->nil) spazio->root = y;" else if (indotto==indotto->genitore->sinistra)" y->genitore->sinistra = y;" else" y->genitore->destra = y;" y->sinistra = indotto; indotto->genitore = y; } void rightrotate(rbtree* perno, rbnode* ghigo) /* questa procedura produce una rotazione necessaria al ripristino delle proprietà dell'alberorb. tempo @(1) */ { rbnode *mm = ghigo->sinistra; ghigo->sinistra = mm->destra; if (mm->destra!=perno->nil) mm->destra->genitore = ghigo;" mm->genitore = ghigo->genitore; if (ghigo->genitore==perno->nil) perno->root = mm;" else if (ghigo==ghigo->genitore->destra)" mm->genitore->destra = mm;" else" mm->genitore->sinistra = mm;" mm->destra = ghigo; ghigo->genitore = mm; } rbnode *cercanodino(rbtree *spazio, int a, int b, int c, int d) /* questa funzione cerca un nodo nell'albero e, in caso lo trovi, ne restituisce il puntatore; in caso contrario restituisce NULL. tempo @(log n) */ { rbnode *buffer = NULL; char macaja; buffer = spazio->root; while(buffer != spazio->nil && (buffer->a != a || buffer->b != b || buffer->c != c || buffer->d != d)) { if(a < buffer->a) macaja = 'y'; else if(a > buffer->a) macaja = 'n'; else if(a == buffer->a && b < buffer->b) macaja = 'y' ; else if(a == buffer->a && b > buffer->b) macaja = 'n'; else if(a == buffer->a && b == buffer->b && c < buffer->c) macaja = 'y'; else if(a == buffer->a && b == buffer->b && c > buffer->c) macaja = 'n'; else if(a == buffer->a && b == buffer->b && c == buffer->c && d <= buffer->d) macaja = 'y'; else macaja = 'n'; if (macaja =='y') buffer = buffer->sinistra ; else buffer=buffer->destra; } if(buffer == spazio->nil) return NULL; else return buffer; } rbalbero *crea_rbalbero(int a) /* questa procedura alloca spazio e inizializza la radice e la sentnella di un albero di tipo rbalbero. tempo @(1) */ { rbalbero *tree = malloc(sizeof(rbalbero)); if(!tree) return NULL;" if(!(tree->root = malloc(sizeof(rbapple)))) return NULL;" tree->nul = tree->root; tree->nul->left = tree->nul->right = tree->nul->parent = tree->nul; tree->nul->co = black; if (a==1)" {" if (!(tree->nul=malloc(sizeof(rbapple))))" exit(-2);" tree->root->left = tree->root->right = tree->root->parent = tree->nul;" }" return tree; } rbapple *trova_nodofoglio(rbalbero *perno, int puntox, int puntoy) /* questa funzione si occupa di trovare un nodo, se esistente, e di restituirne il puntatore. Nel caso in cui il nodo non esista restituisce NULL. tempo @(log n) */ { rbapple *giusto=perno->root; while (giusto!=perno->nul && (giusto->xx!=puntox || giusto->yy!=puntoy)) { if (puntox<giusto->xx) giusto = giusto->left; else if (puntox>giusto->xx) giusto = giusto->right; else if (puntox == giusto->xx && puntoy < giusto->yy) giusto = giusto->left; else giusto = giusto->right; } if (giusto==perno->nul) return NULL;" else return giusto;" } void inserisci_punto(rbalbero* perno, int puntox, int puntoy) /* questa procedura inserisce un nodo in un'albero rb e ne ripristina le proprietà. tempo @(log n) dovuto alla ricerca dello spazio nell'albero */ { rbapple *birba = inserisci_apple(perno, puntox, puntoy); rbapple *cesco; if (birba!=NULL){ while (birba!=perno->root && birba->parent->co==red) { if (birba->parent==birba->parent->parent->left) { cesco = birba->parent->parent->right; if (cesco->co==red) { birba->parent->co = black;" cesco->co = black;" birba->parent->parent->co = red;" birba = birba->parent->parent;" } else { if (birba==birba->parent->right) {" birba = birba->parent;" ruotaasinistra(perno, birba);" }" birba->parent->co = black; birba->parent->parent->co = red; ruotaadestra(perno, birba->parent->parent); } } else { cesco = birba->parent->parent->left; if (cesco->co==red) { birba->parent->co = black;" cesco->co = black;" birba->parent->parent->co = red;" birba = birba->parent->parent;" }
Per quanto riguarda la discussione del progetto fai riferimento a questo file, che contiene anche il file C del progetto.