Oppure

Loading
05/01/08 10:31
spaghetto
Salve ragazzi, sto cercando di fare un esercizio con le liste, soltanto non capisco dove possa essere l' errore...
L' es. consiste nell' unire due liste passate ad una funzione che mi restituisce un puntatore a struttura.

Inoltre NON devo verificare se le liste siano già ordinate.

Ecco qui come ho cercato di svolgere l' esercizio..

allora la struttura è così:

struct node {

  int inf;

  struct node * pun;

};

typedef struct node node;


e invece la mia funzione è questa...dove sbaglio?

node * funz(node * l1, node * l2) {

node * ptr, * succ, * prec;

while(l1!=NULL) {

succ=l1->pun;

prec=NULL;

ptr=l2;

while(ptr!=NULL) {

  if(ptr->inf >= l1->inf) {

    if(prec==NULL) {

       l1->pun=ptr;

       l2=l1;

    }

    else {

        prec->pun=l1;

        l1->pun=ptr;

    }

  }

  prec=ptr;

  ptr=ptr->pun;

  }

  if(succ!=NULL) l1=succ;

  else return l2;

  }

}



Allora quello che cerco di fare è questo:

io ho due liste, l1 ed l2, e l' idea mia è quella di spostare ogni elemento della prima lista nella seconda, in questo modo, mi rimarrebbe diciamo la seconda lista.

Così facendo quando arrivo alla fine ritorno il puntatore alla testa della seconda lista.

Vi ringrazio in anticipo per le risposte!
Ultima modifica effettuata da spaghetto 05/01/08 10:37
aaa
14/01/08 9:54
pierotofy
Ma non basterebbe prendere l'ultimo elemento della lista l1, farlo puntare al primo elemento della lista l2 e poi ritornare un puntatore al primo elemento della lista l1?
Il mio blog: piero.dev
17/01/08 13:38
bangirasu
Come ha detto piero è la migliore soluzione visto che hai detto che sono già ordinate, inoltre se la lista unita deve essere indipendente dalle altre due ti consiglio di fare una copia della uno e della due e poi fare puntare l'ultimo elemento della 2 al primo elemento della 1.
Ultima modifica effettuata da bangirasu 17/01/08 13:38
aaa
19/01/08 17:39
spaghetto
No ragazzi mi sono spiegato male, l' esercizio consisteva sì nella fusione di due liste, ma ordinate! Devo unirle creando questa liste con gli elementi ordinati...
lo avevo risolto in questo modo...
Specifico che le liste dovevano essere inserite in input con gli elementi ordinati...

node * funz(node * l1, node * l2) {
  node * ptr, * succ, * prec;
  while(l1!=NULL) {
     succ=l1->pun;
     prec=NULL;
     ptr=l2;
  while(ptr!=NULL) {
    if(ptr->inf >= l1->inf) {
       if(prec==NULL) {
          l1->pun=ptr;
          l2=l1;
          break;
          }
    else {
        l1->pun=ptr;
        prec->pun=l1;
        break;
    }
  }
  else if(ptr->pun== NULL && ptr->inf < l1->inf) {
          ptr->pun=l1;
          l1->pun=NULL;
          break;
         }
  else {  prec=ptr;
         ptr=ptr->pun;
     }
}
  if(succ!=NULL) l1=succ;
  else return l2;
   }
}


:k:
aaa
20/01/08 23:45
bangirasu
Ah! adesso ho capito! Ogni lista è ordinata ma gli elementi della prima lista non sono tutti minori di ogni elemento della seconda, cioè bisogna fare una cosa del genere:

Lista 1: 1 5 10 15 20 25
Lista 2: 1 7 8 17 31 33 40
Lista risultato: 1 1 5 7 8 10 15 17 20 25 31 33 40

Modo iterativo:
List merge (List LL1, List LL2)
{

/* per comodita` costruisco LL3 che è il "manico" della lista,
 * poi la restituisco senza manico
 */

 List LL3, last, aux;

 LL3 = calloc(1, sizeof(struct cella));
 LL3->next= NULL;

 last= LL3; /* last punta "sempre" all'ultimo record di LL3 */

 while ((LL1 != NULL) && (LL2 !=NULL))
 {
   if ( LL1->cont <= LL2->cont )
   {
    /* copio da LL1 in LL3 */
     aux = calloc(1, sizeof(struct cella));
     aux->cont = LL1->cont;
     aux->next = NULL;

     last->next = aux;
     last = aux;

     LL1 = LL1->next;
   }
   else
   {
    /* copio da LL2 in LL3; simmetrico al precedente */
     aux = calloc(1, sizeof(struct cella));
     aux->cont = LL2->cont;
     aux->next = NULL;

     last->next = aux;
     last = aux;

     LL2 = LL2->next;
   }

 } /* fine del while */

/* a questo punto una delle due liste e` esaurita,
 * ma l'altra no .......
 */

 if (LL1 == NULL)
   while (LL2 != NULL)
   {
     aux = calloc(1, sizeof(struct cella));
     aux->cont = LL2->cont;
     aux->next = NULL;

     last->next = aux;
     last = aux;

     LL2 = LL2->next;
   }
 else
  /* analogo al precedente */
   while (LL1 != NULL)
   {
     aux = calloc(1, sizeof(struct cella));
     aux->cont = LL1->cont;
     aux->next = NULL;

     last->next = aux;
     last = aux;

     LL1 = LL1->next;
   }

 return (LL3->next);
/* cosi' restituisco una lista senza "manico" */
}


Non sarebbe male farla ricorsivamente. Nella Rete ho trovato questa soluzione ricorsiva e funzionante:
void aux_rec_merge (List LL1, List LL2, List *LL)
{
   int *tcont; 
   List TL1 = NULL, TL2 = NULL;
   
   char choice = (LL1 == NULL);
   choice *= 2;
   choice |= (LL2 == NULL);

   switch (choice) {
     case 0:
       if (LL1->cont <= LL2->cont) {
         tcont = &(LL1->cont);
         TL1 = LL1->next;
         TL2 = LL2; }
       else {
         tcont = &(LL2->cont);
         TL1 = LL1;
         TL2 = LL2->next; }
       break;
     case 1:
       tcont = &(LL1->cont);
       TL1 = LL1->next;
       TL2 = LL2;
       break; 
     case 2:
       tcont = &(LL2->cont);
       TL1 = LL1;
       TL2 = LL2->next;
       break;
     default:
       return; }
   
   (*LL) = calloc(1, sizeof(struct cella)); 
   (*LL)->cont = *tcont;
   (*LL)->next = NULL;

   aux_rec_merge(TL1, TL2, &((*LL)->next));  
}

List rec_merge (List LL1, List LL2)
{
  List LL = NULL;
  aux_rec_merge(LL1, LL2, &LL);

  return LL;
}


"rec_merge" si appoggia ad una funzione ausiliaria ricorsiva "aux_rec_merge".

La struct Cella è così definita
typedef struct { int  cont;
                 List next; } Cella;
typedef  Cella * List;
Ultima modifica effettuata da bangirasu 20/01/08 23:47
aaa
21/01/08 13:45
spaghetto
Si in effetti la soluzione ricorsiva andrebbe bene!
Solo che non mi so muovere più di tanto!!!
Cmq l' importante è aver risolto il quesito!
aaa