Oppure

Loading
21/05/11 13:31
Puffetta
Ciao a tutti, devo creare un programma che preso in input un albero binario completo o semicompleto(se la foglia non c'è metto zero), mi stampa la sua visita preordine. Io ho fatto vari tentativi ma il programma va sempre in loop.
Potreste darmi una mano a risolvere questo problema? io programmo da poco e non so bene dove mettere le mani.

Il codice che ho fatto è il seguente:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define SIZE 31

int main()
    {
          int v[SIZE];
          int i=0, padre=0, rad=0;
          
          scanf("%d",&(v[0]));
          scanf("%d %d", &(v[1]),&v[2]);
          scanf("%d %d %d %d", &(v[3]),&v[4], &v[5], &v[6]);
          scanf("%d %d %d %d %d %d %d %d", &(v[7]),&v[8], &v[9], &v[10], &(v[11]), &(v[12]), &(v[13]), &(v[14]));
          scanf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", &(v[15]),&v[16], &v[17], &v[18], &(v[19]), &(v[20]), &(v[21]), &(v[22]), &(v[23]), &(v[24]), &(v[25]), &(v[26]), &(v[27]), &(v[28]), &(v[29]), &(v[30]));         
          
          while(i<SIZE)
                 {
                     if((v[i]==0)&&(i<SIZE))
                            i=2*padre+2;
                            
                     if((v[i]!=0)&&(i<SIZE))
                        {
                            printf("%d\n", v[i]);       
                            
                            //Ho figlio sinistro?
                            if((v[(2*i+1)]!=0)&&((2*i+1)<SIZE))
                                {
                                   padre=i;
                                   i=2*i+1;
                                }
                           
                            else
                               {   
                                   
                                   //se non ho il figlio sinistro, ho il figlio destro?
                                   if((v[2*i+2]!=0)&&((2*i+2)<SIZE))
                                       {
                                          padre=i;
                                          i=2*i+2;
                                       }                                       
                                   //se non ho nessuno dei due cerco di tornare alla prima radice non nulla.
                                   else
                                       {
                                            i++;
                                  
                                            if((v[i]!=0)&&(i<SIZE))   printf("%d\n", v[i]);
                                            
                                            rad=(int)ceil(((double)padre)/2.-1.);
                                            
                                            if((2*i+1<SIZE)&&(2*i+2<SIZE))
                                              {                                  
                                                 if((v[2*i+1]==0)&&(v[2*i+2]==0))
                                                  {
                                                      i=2*rad+2;
                                          
                                                      if(i==padre)
                                                          {
                                                              padre=(int)ceil(((double)rad)/2.-1.);
                                                              i=2*padre+2;     
                                                          }                             
                                                  }
                                              }
                                          
                                            else
                                              {
                                                  i=2*rad+2;
                                                  
                                                  if(i==padre)
                                                      {
                                                          padre=(int)ceil(((double)rad)/2.-1.);
                                                          i=2*padre+2;
                                                          
                                                          if(padre==1)    i=padre++; 
                                                      }                                                              
                                              }     
                                        }
                               }
                        }                     
                 
                 }      
          
          system("PAUSE");
          return 0;
    }
Ultima modifica effettuata da Puffetta 21/05/11 13:33
aaa
21/05/11 14:29
Oligoatria
Non penso sia la strada migliore. Google risponde bene alla ricerca "visita preorder C". Una semplice realizzazione è al link

it.wikipedia.org/wiki/Visita_pre-order

void PreOrder(nodo)
{
if ( nodo == NULL ) return;
visita( nodo );
PreOrder( nodo->sinistra );
PreOrder( nodo->destra );
return;
}

Naturalmente questo necessita di una struttura dati di qualità migliore, diciamo. Ti consiglio dunque, se non l'hai già fatto, di prendere confidenza con i concetti di "puntatore" e "ricorsione". Di libri, guide ecc. ne trovi facilmente su google.
Piuttosto che far fatica inutilmente, secondo me, ti conviene imparare questi concetti basilari che ti saranno utili in molte altre cose.
aaa
21/05/11 16:19
Puffetta
hai pienamente ragione a riguardo, ma mi è stata imposta la seguente realizzazione iterativa...
aaa
21/05/11 16:34
Ultimo

Se rimane in loop vuol dire che i rimane sempre inferiore a 31
If ok Then GOTO Avanza else GOTO Inizia

21/05/11 21:40
Puffetta
si, l'avevo pensato anche io, ma il problema è che qualsiasi altra condizione io imposti o è inutile e quindi continua ad andare in loop o mi blocca l'esecuzione del programma.
aaa
22/05/11 3:53
pierotofy
:noway:

Ricomincia da capo. Quel codice è un guazzabuglio. Se devi utilizzare il C che non ti offre gli stack, utilizza un array per simulare uno stack (un push assegna il valore all'elemento corrente e incrementa l'indice, un pop decrementa l'indice).

en.wikipedia.org/wiki/…

public void iterativePreorder(Node root) {
   Stack nodes = new Stack();
   nodes.push(root);
   Node currentNode;
   while (! nodes.isEmpty()){
      currentNode = nodes.pop();
      Node right = currentNode.right();
      if (right != null)
         nodes.push(right);
      Node left = currentNode.left();
      if (left != null)
         nodes.push(left);      
      System.out.println("Node data: "+currentNode.data);
   }
}


en.wikipedia.org/wiki/…
Il mio blog: piero.dev
22/05/11 14:26
Puffetta
so che praticamente per fare questo programma ci sono metodi e strutture migliori di quelle che uso, ma mi è stato imposto di farlo senza ricorsione e ci sono stati insegnati a stento i puntatori, quindi io non so usare tutte queste strutture comode che mi chiedete di fare
aaa
22/05/11 16:40
pierotofy
Ti sono stati insegnati gli array e bastano ed avanzato per simulare uno stack. E non è magia nera. Hai letto la pagina che ti ho linkato? Hai capito cos'è uno stack? Dopo che hai capito quello, implementare l'algoritmo che ti ho riportato dovrebbe essere piuttosto semplice. Se hai dubbi chiedi.
Il mio blog: piero.dev