Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 22
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    14

    [C] funzione partizione quickSort

    Buongiorno a tutti è il mio primo post,vi scrivo per un piccolo problema che mi sta facendo sclerare da 3 giorni;in un esercizio mi si chiede di implementare la funzione di partizione per poi successivamente utilizzarla nel quicksort;il mio problema è proprio questa funzione di partizione.
    La funzione prende come parametri l'array da ordinare,l'indice dell'elemento pivot in base al quale spostare tutti gli elementi più piccoli a sinistra e più grandi a destra(ovviamente l'indice deve essere compreso fra gli estremi),l'estremo sinistro e l'estremo destro e restituisce l'indice della posizione del pivot alla fine dell'ordinamento.
    Io l'ho scritta così:

    int partiziona(int a[],int i,int l,int r){
    int pivot=a[i];
    while(l<r){
    while(a[l]<pivot)
    l=l+1;
    while(pivot<a[r])
    r=r-1;
    if(l<r){
    int tmp=a[l];
    a[l]=a[r];
    a[r]=tmp;
    }
    }
    return l;
    }

    testata su un array qualsiasi funziona a patto che nell'array non vi siano valori uguali al pivot,altrimenti va in stallo.Mi sono quindi accorto che la funzione andava ovviamente in stallo in quanto avrei dovuto scrivere <= e non < ma se provo ad effettuare questa modifica la funzione non ordina correttamente in base al pivot e restituisce quindi un valore sbagliato anche nel caso di array con tutti gli elementi diversi.Le ho provate di tutte sapreste dirmi cosa c'è da aggiungere per farla funzionare? Sono nelle vostre mani...

  2. #2
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    14
    Vedo che mi avete aiutato in molti...
    Comunque sono riuscito a risolvere il problema modificando l'implementazione in questo modo:
    codice:
    /*VERSIONE OTTIMIZZATA*/
    int partiziona(Item a[],int i,int l,int r){
        Item pivot=a[i];                     //il pivot vale a[i] dove i è compreso fra l e r inclusi
        while(l<r){                            //finchè l è minore di r esegui il corpo
            while(!isMaggiore(a[l],pivot)) //scorrendo da sinistra mi fermo
                l=l+1;                          //quando trovo un elemento maggiore del pivot
            while(!isMaggiore(pivot,a[r])) //scorrendo da destra mi fermo
                r=r-1;                          //quando trovo un elemento minore del pivot
            if(l<r){                            //se l è minore di r allora effettuo lo scambio e 
                scambia(&a[l],&a[r]);    //itero altrimenti non scambio ed esco 
            }
        }
        if (i>l){                               //quando l >= r allora tutto l'array è ordinato ripsetto al 
            scambia(&a[i],&a[l]);        //meno il pivot stesso che però è rimasto nella
            return l;                        //posizione iniziale quindi lo scambio con l o r a 
        }                                     //seconda se i si trova a destra di l o a sinistra di r e ritorno 
        else{                               //il nuovo indice corrente del pivot
            scambia(&a[i],&a[r]);
            return r;
        }   
    }
    e funziona correttamente,l'unica cosa che non capisco è perchè per array molto grandi tipo che ne so 10 milioni di elementi la funzione da errore in esecuzione qualcuno sa illuminarmi?

  3. #3
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Nessuno ti risponderà se non indichi "in dettaglio" di quale "errore in esecuzione" parli ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  4. #4
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    14
    Come si fa a capire che tipo di errore di esecuzione sia? cioè io l'unica cosa che vedo è l'apertura della finestrella di windows che mi dice "si è verificato un errore di esecuzione l'applicazione verrà chiusa"...Esiste magari un modo per vedere il numero dell'errore o cose simili?

    Perchè ripeto con errore di esecuzione intendo non che mi restituisce i valori sbagliati ma quanto detto sopra ovvero l'applicazione crasha;io credo sia qualcosa dovuto alla memoria più che alla correttezza del codice...

  5. #5
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Originariamente inviato da 10tony89
    Come si fa a capire ...
    Quella è già un'indicazione di errore importante (anche se a te non dice molto ...) in quanto indica (con molta probabilità) un problema di puntatori; e se la leggessi con precisione, sapremmo se si è verificata durante un accesso in "lettura" o in "scrittura".

    In piu', se metti qualche breakpoint (o qualche printf opportunamente inserito ...), individui anche la linea che "causa" l'errore ...

    Così aiuti noi (e te stesso) a capire qual è la causa dell'errore, la linea che la genera e determini la soluzione.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  6. #6
    Utente di HTML.it
    Registrato dal
    Jun 2007
    Messaggi
    153
    Originariamente inviato da 10tony89
    e funziona correttamente,l'unica cosa che non capisco è perchè per array molto grandi tipo che ne so 10 milioni di elementi la funzione da errore in esecuzione qualcuno sa illuminarmi?
    ma non potrebbe essere che 10.000.000*32bit=32.000.000.000bit=4.000.000.000 byte=4GB quindi magari finisce la memoria a disposizione?
    potrebbe essere anche una grandissima stupidata era per provare...
    cogli l'attimo

  7. #7
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Originariamente inviato da c_junior
    ma non potrebbe essere che 10.000.000*32bit=32.000.000.000bit=4.000.000.000
    Scusa ... mi spieghi questi calcoli ?

    10 milioni di interi occupano 40 MB ... non 4 GB ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  8. #8
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    14
    Non so come fare a vedere se l'errore sia in uscita o in entrata vi mostro anche il main dove ho testato l'applicazione e come potete vedere la funzione funziona se cambiate però la const N con numeri grandi come ad esempio 1 miliardo crasha. Per vedere i risultati più velocemente non fate stampare a video per numeri grandi nel main.

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    typedef int Item;
    
    void stampa(int* v,int x){
        int i;
        for(i=0;i<x;i++)
            printf("%d**",*(v+i));
    }
    
    int isMinore(Item a,Item b){
        if(a<b)
            return 1;
        return 0;
    }
    int isMaggiore(Item a,Item b){
        if(a>b)
            return 1;
        return 0;
    }
    void scambia(Item* a,Item* b){
        Item tmp=*a;
        *a=*b;
        *b=tmp;
    }
    
    int partiziona(Item a[],int i,int l,int r){
        Item pivot=a[i];  //il pivot vale a[i] dove i è compreso fra l e r inclusi
        while(l<r){      //finchè l è minore di r esegui il corpo
            while(!isMaggiore(a[l],pivot)) //scorrendo da sinistra mi fermo
                l=l+1;          //quando trovo un elemento maggiore del pivot
            while(!isMaggiore(pivot,a[r])) //scorrendo da destra mi fermo
                r=r-1;         //quando trovo un elemento minore del pivot
            if(l<r){         //se l è minore di r allora effettuo lo scambio e 
                scambia(&a[l],&a[r]);  //itero altrimenti non scambio ed esco 
            }
        }
        if (i>l){     //quando l >= r allora tutto l'array è ordinato ripsetto al 
            scambia(&a[i],&a[l]); //meno il pivot stesso che però è rimasto nella
            return l;       //posizione iniziale quindi lo scambio con l o r a 
        }          //seconda se i si trova a destra di l o a sinistra di r e ritorno 
        else{        //il nuovo indice corrente del pivot
            scambia(&a[i],&a[r]);
            return r;
        }   
    }
    
    const int N=100;
    
    int main(){
        srand(time(NULL));
        int* vettore=malloc(N*sizeof(int));
        int i;
        time_t t0, t1;
        for(i=0;i<N-1;i++)
           vettore[i]=rand();
        stampa(vettore,N);
        time(&t0);
        int x=partiziona(vettore,8,0,N-1);
        printf("\n%d\n",x);
        time(&t1);
        stampa(vettore,N);
        printf("\nCi ho messo %f secs a ordinare %d elementi\n",difftime(t1,t0), N);
    scanf("%d",&i);
    return 0;
    }

  9. #9
    Utente di HTML.it
    Registrato dal
    Jun 2007
    Messaggi
    153
    Originariamente inviato da oregon
    Scusa ... mi spieghi questi calcoli ?

    10 milioni di interi occupano 40 MB ... non 4 GB ...
    si si hai pienamente ragione te ho fatto il calcolo su 10miliardi...scusate
    cogli l'attimo

  10. #10
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Originariamente inviato da 10tony89
    ... ad esempio 1 miliardo crasha ...
    Capiamoci .... avevi detto 10 milioni ... con 1 miliardo è ovvio che ci sia un crash dato che, in quel caso, vuoi occupare 4 G e non li può allocare ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.