Funzione ricorsiva

di il
8 risposte

Funzione ricorsiva

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

  • Re: Funzione ricorsiva

    "Ho un problema" non vuol dire molto

    E poi perché apri un altro thread?
  • Re: Funzione ricorsiva

    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.
  • Re: Funzione ricorsiva

    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.
  • Re: Funzione ricorsiva

    Grazie mille, ma ho fatto i cambi che mi hai suggerito ma il numero k viene ancora stampato in testa alla lista
  • Re: Funzione ricorsiva

    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?
  • Re: Funzione ricorsiva

    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;
    }
    
    
    
  • Re: Funzione ricorsiva

    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.
  • Re: Funzione ricorsiva

    Grazie mille veramente, sono stato io a aver messo la lista al contrario
Devi accedere o registrarti per scrivere nel forum
8 risposte