Mantenere in albero solo nodi Item con un certo campo

di il
12 risposte

Mantenere in albero solo nodi Item con un certo campo

Ciao, vorrei fare un algoritmo che , dato un albero di nodi Item mi cancellasse quelli con campo prodotto >34 e mi facesse invece rimanere nell’albero i nodi con campo prodotto <34. A parte il fatto che non riesco a fare la cancellazione , ho pensato che ci sarei arrivata pian piano. Ho creato per prima cosa una funzione che mi stampa solo i nodi con campo <34 ma non sono riuscita nemmeno in questo.. i nodi stampati sono si tutti <34 ma ne mancano molti all’elenco e non ho idea di dove ho sbagliato


code]

if (h == 0) // se albero è vuoto ritorno 0
 return 0;
 if ( h != 0 && h->item.getprodotto() < 34 ) // se nodo è diverso da 0 e il nodo contiene un item con campo prodotto <34
 {
 cout << h->item.key() << " " << h->item.getprodotto() << " " << endl; // allora ritorno chiave dell’item ( nome ) e relativo campo prodotto
 return 1;
 }
 
 [/code]

12 Risposte

  • Re: Mantenere in albero solo nodi Item con un certo campo

    Ma riesci a stampare tutto l'albero?
  • Re: Mantenere in albero solo nodi Item con un certo campo

    L’albero lo stampo con una funzione a parte vista a lezione , che riporto qui. In questo caso stampo con visita in-order
    
     void showR(link h, ostream& os)
            { 
              if (h == 0) return;
    		  
    		  showR(h->l, os);
    		  h->item.show(os);
              showR(h->r, os);
            }
    
  • Re: Mantenere in albero solo nodi Item con un certo campo

    Fai cosi':

    partendo dalla funzione che stampa tutto l'albero, sotituisci la riga usata per stampare il contenuto del nodo con una FUNZIONE che riceve come parametro il nodo e nella sua implementazione stampa il contenuto del nodo.

    controlla che stampi tutto l'albero

    all'interno della funzione appena creata, aggiungi la condizione di tuo interesse.

    Ma questo NON RISOLVE il problema.
    La cancellazione di un nodo in un albero si fa in questo modo

    0) si possono cancellare SOLO i nodi foglia
    1) se il nodo e'intermedio, va SCAMBIATO con un nodo foglia
    2) cancelli il nodo foglia

    qualunque libro che tratta algoritmi e strutture dati ti mette a disposizione n-mila modi per fare questa operazione.
  • Re: Mantenere in albero solo nodi Item con un certo campo

    Come parte privata del file bst.h
    
    
    Item showItemR(link h)
       {
    	   if (h == 0) return nullItem;
    
    	   else
    		   return h->item;
       }
    
    
      void showandcancelR(link& h, ostream& os)
            { 
              if (h == 0) return;
    		  
    		  showandcancelR(h->l, os);  
              showandcancelR(h->r, os); 
    		  
    		  if (h < 34) {
    			  return showItemR(h);
    		  }
    
    
            }
            
            
    come parte pubblica del file bst.h
    
    
    Item showItemR(int k) {
    
    		  return showItemR(head, k);
    	  }
    
    	  void showandcancelR(link h, ostream& os) {
    
    		  showandcancelR(head, os);
    
    	  }
    
    
    a parte il fatto che non ho ancora affrontato la cancellazione del nodo , devo aver fatto più di un disastro temo.. ho provato a seguire le istruzioni ma devo aver scritto più di un abominio perchè è decisamene lontano dal funzionare. durante il corso ci è stato consigliato di studiare sulle slide e sugli esercizi o temi di esame del corso. scorrendo tutto il materiale ho trovato una funzione che credevo mi potesse aiutare e che cancellava tutti i nodi foglia di un albero che avessero come nodo item avente un codice <23. pensavo che togliendo la condizione dei nodi foglia
       h->l == 0 && h->r == 0   
    mi sarei avvicinata ma modificandola arrivo alla soluzione postata prima..

    
    
    int contafoglieR(link& h)
       {
    	   if (h == 0)
    		   return 0;
    	   if (h->l == 0 && h->r == 0 && h->item.getcodice()<=23)
    	   {
    		   cout << h->item.key() << " ";
    		   return 1;
    	   } 
    	   else
    		   return contafoglieR(h->l) + contafoglieR(h->r);
       }
    
    
    
    
    
  • Re: Mantenere in albero solo nodi Item con un certo campo

    Sarebbe opportuno capire prima cosa funziona e partire da lì.
  • Re: Mantenere in albero solo nodi Item con un certo campo

    Per stampare solo i nodi che vuoi tu basta inserire un if in showR prima di chiamare la show.
  • Re: Mantenere in albero solo nodi Item con un certo campo

    Aggiungendo la condizione prima della show e richiamando la funzione nel main , non ho errori ma non mi viene stampato nessun elemento dell'albero..qui ho usato la condizione che appunto ogni nodo item dell'albero abbia un campo prodotto
    
    
    void shownodogiustoR(link h, ostream& os)
       {
    	   if (h == 0) return;
    
    
    	   if (h->item.getprodotto() < 34) {
    		   shownodogiustoR(h->l, os);  // da in algoritmo in order , spostando la visita della radice come ultimo passaggio, siamo passatia algortimo post order
    		  // h->item.show(os);
    		   shownodogiustoR(h->r, os);
    		   h->item.show(os);
    	   }
       }
    
    
  • Re: Mantenere in albero solo nodi Item con un certo campo

    Certo è ovvio, così blocchi la ricorsione al primo elemento che non soddisfa la condizione. Io intendevo così (mantenendo la visita in-ordine, se vuoi):
    
    void shownodogiustoR(link h, ostream& os)
       {
       	if (h == 0) return;
    	shownodogiustoR(h->l, os); 
    	if (h->item.getprodotto() < 34) 
    		h->item.show(os);
    	shownodogiustoR(h->r, os);
       }
    
    EDIT: se vuoi bloccare la ricorsione, puoi impedire di scansionare il sottoalbero destro nel momento in cui trovi un numero >34.
  • Re: Mantenere in albero solo nodi Item con un certo campo

    Grazie mille!! ora almeno mi stampa solo quelli corretti. quindi almeno esteticamente l'output è quello giusto , anche se devo ancora trovare un modo per cancellare quelli non selezionati
  • Re: Mantenere in albero solo nodi Item con un certo campo

    
    
    For (L2.moveToStart(); L2.currPos() < L2.length(); L2.next())
    	  {    
    
    		  it = L2.getValue();
    
    		  if (it.prodotto() < 34)
    		 
    		  Albero.remove(it);
    
    
    	  } 
    probabilmente scrivo l'abominio del secolo.. non si potrebbe utilizzare una lista come supporto per cancellare gli elementi dell'item ? scorro una lista L2 dove precedentemente ho inserito tutti i nodi dell'albero. a mano a mano che scorro , estraggo l'item e se quell'item ha un codice < 34 allora faccio una remove sull'albero. perdonatemi se quello che ho scritto è molto stupido
  • Re: Mantenere in albero solo nodi Item con un certo campo

    Se non ci sono ci sono modiche sui valori, può anche andare. Certo, richiede più memoria. Almeno cancella l'elemento dalla lista man mano che procedi.

    Ce l'hai una funzione che cancella l'intero albero? Se sì, puoi chiamarla sul sottoalbero destro del primo nodo >34 che trovi, per poi eliminare esso stesso. Però può dare problemi se stai usando un albero bilanciato.
    Un altro modo è fare una funzione che cancella un nodo e ti restituisce il successivo (vedi algoritmo ricerca del successivo).
  • Re: Mantenere in albero solo nodi Item con un certo campo

    GRAZIE !!!!!!! funziona e sono quasi commossa per il fatto che il mio metodo contorto abbia un po di senso
Devi accedere o registrarti per scrivere nel forum
12 risposte