Algoritmi e strutture dati/Progetti/Rettangoli/Stesura I

Da WikiDsy.
Versione del 8 mar 2006 alle 13:08 di Yoruno (discussione | contributi) (Riportata alla revisione precedente da Yoruno)
(diff) ← Versione meno recente | Versione attuale (diff) | Versione più recente → (diff)
  #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.