Funzione ricorsiva

di Anonimizzato30947 il
8 risposte
Un ultima cosa, ho un problema con questo esercizio qualcuno riesce a aiutarmi??
Data una lista ordinata in modo crescente, e un valore k, si inserisca k nella lista in modo tale che essa sia ancora ordinata (da fare in maniera ricorsiva)
#include <stdio.h>
#include <stdlib.h>


struct elem {
	int k;
	struct elem *next;
};

struct elem *nuovoElemento(int k){
	struct elem *nuovo= (struct elem *)malloc(sizeof(struct elem));
	nuovo->k=k;
	nuovo->next=NULL;
	return nuovo;
}

struct elem *insElemInTesta(struct elem *top,int k){
	struct elem *nuovo= nuovoElemento(k);
	nuovo->next=top;
	return nuovo;
}

struct elem *insElemInMezzo(struct elem *top,struct elem *pre,int k){
	struct elem *nuovo= nuovoElemento(k);
	if (pre==NULL) {
		nuovo->next=top;
		top=nuovo;
	}
	else {
		nuovo->next=pre->next;
		pre->next=nuovo;
	}
	return top;
}

struct elem *eliminaLista(struct elem *top){
	struct elem *c;
	while (top != NULL){
		c=top;
		top=c->next;
		free(c);		
	}
	return top;
}

struct elem *riempiLista(){
	struct elem *top=NULL;
	int n,i,k;
	printf("Quanti elementi vuoi inserire?");
	scanf("%d",&n);
	for (i=0;i<n;++i) {
		printf("Dammi l'elemento %d:",i+1);
		scanf("%d",&k);
		top=insElemInTesta(top,k);
	}
	return top;
}

void stampaLista(struct elem *top){
	while (top!=NULL) {
		printf("%d -->",top->k);
		top=top->next;
	}
	printf("NULL\n");
}

struct elem *InserisciOrdinato(struct elem *top, int k){
    struct elem* curr;
    if(top==NULL) top=insElemInTesta(top,k);
    if(top->k>k) top=insElemInTesta(top,k);
    else{
        curr=InserisciOrdinato(top->next,k);
        top->next=curr->next;
        curr->next=top;
        top=curr;
    }
    return top;
}

int main()
{
    int k;
    struct elem* top;
    top=riempiLista();
    printf("Dammi elemento k:");
    scanf("%d",&k);
    top=InserisciOrdinato(top,k);
    stampaLista(top);
    top=eliminaLista(top);
    return 0;
}
Grazie mille in anticipo

8 Risposte

  • "Ho un problema" non vuol dire molto

    E poi perché apri un altro thread?
  • oregon ha scritto:


    "Ho un problema" non vuol dire molto

    E poi perché apri un altro thread?
    perché riguarda un altro esercizio; il problema é che in ogni caso l´elemento k viene messo sempre in testa.
  • Metti un return nel primo if di InserisciOrdinato, o metti un else prima del successivo, in modo che entri i nell'uno o nell'altro.

    Per quanto riguarda l'ultimo else
    
     else{
            curr=InserisciOrdinato(top->next,k);
            top->next=curr; 
        }
    
    Va restituito un nuovo top alla chiamata precedente solo se questo corrisponde effettivamente alla nuova testa della lista. L'altra istruzione era ridondante.
    Notare che nella RiempiLista puoi chiamare direttamente InserisciOrdinato (previa dichiarazione) per aggiungere gli elementi, così è già ordinata in automatico.
    Infine, impara a dichiarare le struct con typedef, così puoi fare a meno di ripetere la parola "struct" ogni volta.
  • Grazie mille, ma ho fatto i cambi che mi hai suggerito ma il numero k viene ancora stampato in testa alla lista
  • Così?
    
    struct elem *InserisciOrdinato(struct elem *top, int k){
        struct elem* curr;
        if(top==NULL) 
       	top=insElemInTesta(top,k);
        else if(top->k>k) top=insElemInTesta(top,k);
        else{
            curr=InserisciOrdinato(top->next,k);
            top->next=curr; 
        }
        return top;
    }
    
    Che sequenza hai inserito?
  • Questo é il codice attualmente
    In input metto 3 interi (1,2,4) e come k metto 3 ma in ogni caso me lo inserisce sempre in testa
    Ho aggiunto anche il return nel primo if in una versione precedente ma non é cambiato niente
    #include <stdio.h>
    #include <stdlib.h>
    
    
    struct elem {
    	int k;
    	struct elem *next;
    };
    
    struct elem *nuovoElemento(int k){
    	struct elem *nuovo= (struct elem *)malloc(sizeof(struct elem));
    	nuovo->k=k;
    	nuovo->next=NULL;
    	return nuovo;
    }
    
    struct elem *insElemInTesta(struct elem *top,int k){
    	struct elem *nuovo= nuovoElemento(k);
    	nuovo->next=top;
    	return nuovo;
    }
    
    struct elem *insElemInMezzo(struct elem *top,struct elem *pre,int k){
    	struct elem *nuovo= nuovoElemento(k);
    	if (pre==NULL) {
    		nuovo->next=top;
    		top=nuovo;
    	}
    	else {
    		nuovo->next=pre->next;
    		pre->next=nuovo;
    	}
    	return top;
    }
    
    struct elem *eliminaLista(struct elem *top){
    	struct elem *c;
    	while (top != NULL){
    		c=top;
    		top=c->next;
    		free(c);		
    	}
    	return top;
    }
    
    struct elem *riempiLista(){
    	struct elem *top=NULL;
    	int n,i,k;
    	printf("Quanti elementi vuoi inserire?");
    	scanf("%d",&n);
    	for (i=0;i<n;++i) {
    		printf("Dammi l'elemento %d:",i+1);
    		scanf("%d",&k);
    		top=insElemInTesta(top,k);
    	}
    	return top;
    }
    
    void stampaLista(struct elem *top){
    	while (top!=NULL) {
    		printf("%d -->",top->k);
    		top=top->next;
    	}
    	printf("NULL\n");
    }
    
    struct elem *InserisciOrdinato(struct elem *top, int k){
        struct elem* curr;
        if(top==NULL) 
       	  top=insElemInTesta(top,k);
        else if(top->k>k) top=insElemInTesta(top,k);
        else{
            curr=InserisciOrdinato(top->next,k);
            top->next=curr; 
        }
        return top;
    }
    
    int main()
    {
        int k;
        struct elem* top;
        top=riempiLista();
        printf("Dammi elemento k:");
        scanf("%d",&k);
        top=InserisciOrdinato(top,k);
        stampaLista(top);
        top=eliminaLista(top);
        return 0;
    }
    
    
    
  • Come da traccia, deve funzionare su liste ordinate in ordine crescente. Tu gli hai dato una lista in ordine decrescente (inserimento in testa, cioè l'ultimo è il primo). Prova a dargli 4, 2, 1 e k=3 vedi che funziona.
    Come ho detto, puoi anche usare direttamente InserisciOrdinato in RiempiLista, così puoi inserire numeri a caso che vengono già ordinati.
  • Grazie mille veramente, sono stato io a aver messo la lista al contrario
Devi accedere o registrarti per scrivere nel forum
8 risposte