MergeSort iterativo.

di il
5 risposte

MergeSort iterativo.

Mi sono cimentato nella scrittura di un MergeSort iterativo attraverso le strutture Stack, seguendo la logica di una struttura ad albero. E' questo è il codice che ne è venuto fuori:
typedef struct S *stackL;
typedef struct S 
        {
        int low;
        int up;
        int visite;
        stackL link;
        }
        stack;


void MergeSort (float *A, int low, int up){
     stackL head;
     int vis;
     head=new stack;
     // Inserire dimensione totale dell'array  (0...n).
     Push(head, low, up, 0);
     // Ripetere il ciclo fin quando lo stack non è vuoto.
     while (head!=NULL){
           Pop (head, &low, &up, &vis);
           Push (head, low, up, vis+1);
           int mid=(low+up)/2;
           //Se la dimensione dell'array è 1 eliminare l'ultimo pezzo di stack.
           if(low>=up)
                Pop(head, &low, &mid, &vis);
           //Se è la 1° volta che si prende in considerazione la porzione di array, si crea un nuovo pezzo di stack con la sua parte sx.
           else if (vis==0)
                Push(head, low, mid, 0);
           //Se è la 2° volta che si prende in considerazione la porzione di array, si crea un nuovo pezzo di stack con la sua parte dx.
           else if(vis==1)
                Push(head, mid+1, up, 0);
           //Se la parte di array è già stata divisi in 2 porzioni, la si mette in ordine e la si elimina.
           else{
                Merge(A, low, mid, up);
                Pop(head, &low, &up, &vis);
                }
           }
     delete head;
     }


La logica che ho seguito è quella schematizzata in questo disegno che considera un array di dimensione 8: http://imageshack.com/a/img580/2231/cice.jp.

La funzione push crea un nuovo pezzo di stack con i dati passatogli e lo inserisce in testa allo stack.
La funzione pop estrae il pezzo in testa allo stack e restituisce i valori acquisiti dal pezzo rimosso.

Quando vado a compilare il programma non mi dà alcun genere di errore sintattico, ma quando lancio il programma, arrivato al punto di restituirmi l'array, il programma crasha. Le funzioni Push, Pop e Merge funzionano poichè le ho provate su altri programmi e non mi danno alcun genere di problemi; il main è una banale scrittura e stampa di array e non vi sono errori in quanto anche quello funziona in altri programmi, quindi immagino il problema sia qui, ma non riesco proprio a trovarlo =/. Se avete bisogno anche del main e delle rimanti funzioni, chiedete pure =). Ovviamente non vi chiedo di riscrivermi il codice, ma di aiutarmi a capire eventuali errori logici.

5 Risposte

  • Re: MergeSort iterativo.

    Potresti indicare quale tipo di eccezione ti da ?
    o se il programma va in loop infinito. o che tipo di crash ti dà.
    così ci faciliti il compito di aiutarti.
  • Re: MergeSort iterativo.

    smalldragon ha scritto:


    potresti indicare quale tipo di eccezione ti da ?
    o se il programma va in loop infinito. o che tipo di crash ti dà.
    così ci faciliti il compito di aiutarti.
    Uso devc++ e semplicemente mi dice che il programma ha smesso di funzionare dopo che ho dato l'array in imput...
  • Re: MergeSort iterativo.

    Posta la main
  • Re: MergeSort iterativo.

    smalldragon ha scritto:


    posta la main
    Eccoti l'intero programma =)
    #include<iostream>
    using namespace std;
    
    typedef struct S *stackL;
    typedef struct S 
            {
            int low;
            int up;
            int visite;
            stackL link;
            }
            stack;
    
    void Push (stackL &head, int low, int up, int vis);
    void Pop (stackL &head, int *low, int *up, int *vis);
    void MergeSort (float *A, int low, int up);
    void Merge (float *A,int low,int mid,int up);
    
    int main(){
        float *a;
        int n, i;
        cout<< "Inserire dimensione array: ";
        cin>> n;
        a=new float[n];
        for (i=0; i<n;i++){
            cout<<"Inserire "<<i+1<<"° valore dell'array: ";
            cin>>a[i];
            }
        MergeSort(a,0,n-1);
        cout<<"L'array ordinato è: ";
        for (i=0; i<n ; i++)
            cout<< a[i] << " " ;
        cout<<endl;
        delete [] a;
        system("pause");
        return 0;
        }
           
           
           
    void MergeSort (float *A, int low, int up){
         stackL head;
         int vis;
         head=new stack;
         // Inserire dimensione totale dell'array  (0...n).
         Push(head, low, up, 0);
         // Ripetere il ciclo fin quando lo stack non è vuoto.
         while (head!=NULL){
               Pop (head, &low, &up, &vis);
               Push (head, low, up, vis+1);
               int mid=(low+up)/2;
               //Se la dimensione dell'array è 1 eliminare l'ultimo pezzo di stack.
               if(low>=up)
                    Pop(head, &low, &mid, &vis);
               //Se è la 1° volta che si prende in considerazione la porzione di array, si crea un nuovo pezzo di stack con la sua parte sx.
               else if (vis==0)
                    Push(head, low, mid, 0);
               //Se è la 2° volta che si prende in considerazione la porzione di array, si crea un nuovo pezzo di stack con la sua parte dx.
               else if(vis==1)
                    Push(head, mid+1, up, 0);
               //Se la parte di array è già stata divisi in 2 porzioni, la si mette in ordine e la si elimina.
               else{
                    Merge(A, low, mid, up);
                    Pop(head, &low, &up, &vis);
                    }
               }
         delete head;
         }
         
         
         
         
         
    void Merge (float *A,int low,int mid,int up){
         float *B;
         int f, newlow=0, newup=(up-low+1), c=0, newmid=(newup+newlow)/2;
         B= new float[newup];     
         for(f=low;f<=up;f++){
                 B[c]=A[f];
                 c++;
                 }
         int i=0, k=low, j=newmid;
         while (i<newmid && j<newup){
               if(B[i]<B[j]){
                    A[k]=B[i];
                    i++; 
                    }
               else{
                    A[k]=B[j];
                    j++;
                    }
               k++;
               }
         if (i>=newmid)
             for (f=j;f<newup;f++){
                A[k]=B[f];
                k++;
                }
         else
             for (f=i;f<newmid;f++){
                 A[k]=B[f];
                 k++;
                 }
         delete [] B;
         }     
         
         
           
           
    void Push (stackL &head, int low, int up, int vis){
                   stackL app;
                   app= new stack;
                   app->low=low;
                   app->up=up;
                   app->visite=vis;
                   app->link=new stack;
                   app->link=head;
                   head=app;                           
    }        
         
         
         
    void Pop (stackL &head, int *low, int *up, int *vis){    
         if(head!=NULL){
         stackL app=head->link;
         *low=head->low;
         *up=head->up;
         *vis=head->visite;
         delete head;
         head=app;
         }
    }
  • Re: MergeSort iterativo.

    Allora fondamentalmente ci sono 3 problemi.
    1) la routine mergesort va in loop infinito arrivando ad allocare elementi del vettore non definiti.
    2) cosi come è il programma il merge viene sempre effettuato dai primi 2 record ciò dipende dal fatto che non viene incrementata la variabile vis.
    3) non viene gestita la condizione per effettuare lo scambio dell'ultimo elemento in caso di vettore con elementi dispari.
    un consiglio che ti posso dare è quello di impostare la condizione di uscita quando non avvengono più scambi.
    quando hai un vettore con numero di elementi dispari tramutalo in pari aggiungendo uno zero alla fine, che naturalmente non potrai accettare come valore.
Devi accedere o registrarti per scrivere nel forum
5 risposte