n° 185
Maggio/Giugno 2013
Maggio 25, 2013, 02:26:59 pm *
Benvenuto! Accedi o registrati.
Hai dimenticato l'e-mail di attivazione?

Accesso con nome utente, password e durata della sessione
Notizia:
 
   Indice   Linux Windows Techassistance Gameassistance videogame hardware Aiuto Ricerca Agenda Downloads Accedi Registrati  

* Messaggi recenti
Messaggi recenti
Pagine: [1]   Vai giù
  Stampa  
Autore Discussione: [C++]Sort in lista  (Letto 941 volte)
0 utenti e 1 Utente non registrato stanno visualizzando questa discussione.
jappoz92
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 8


Mostra profilo E-mail
« inserita:: Giugno 20, 2012, 11:41:55 am »

Salve, sto creando una lista in C++ e dovrei creare anche un metodo di sort (a piacere, non importa la complessità)
Ho elaborato una cosa del genere ma quando eseguo mi si blocca il programma (non sono sicuro per giunta che la sintassi sia corretta). Qualcuno potrebbe aiutarmi a capire dove è sbagliato ed eventualmente a metterla a posto?
Posto il codice
Codice:
void List::Sort( void ){

    if( IsEmpty() ){

cout << "Lista VUOTA" << endl;
return;

}

    ListNode *currentPtr = firstPtr -> nextPtr;

    while( currentPtr != 0 ){

        if( currentPtr -> data > currentPtr -> nextPtr -> data ){

            int aux = currentPtr -> data;
            currentPtr -> data = currentPtr -> nextPtr -> data;
            currentPtr -> nextPtr -> data = aux;

        }

     currentPtr = currentPtr -> nextPtr;

    }

return;

}

e qui i prototipi delle classi List e ListNode

Codice:

#ifndef LIST_H
#define LIST_H
#include <iostream>
#include "ListNode.h"                 //il file dove è definita la classe ListNode (ovvero il singolo nodo della lista)


class List{

public:

List();                               //  costruttore
~List();                              //  distruttore
void InserisciCima( const int& );     //  inserisce un elemento in cima alla lista
void InserisciFondo( const int& );    //  inserisce un elemento in fondo alla lista
bool IsEmpty( void ) const;           //  restituisce true se la lista è vuota
void Print( void ) const;             //  stampa a video la lista
bool RimuoviCima( int& );             //  rimuove un elemento dalla cima, copia il valore nel nodo passato a parametro e restituisce true se l' operazione va a buon fine
bool RimuoviFondo( int& );            //  rimuove un elemento dal fondo, copia il valore nel nodo passato a parametro e restituisce true se l' operazione va a buon fine
        bool Search( const int& );            //  ricerca il valore passato al metodo e restituisce true se lo trova
        void Sort( void );                    //  algoritmo di sort a piacere

private:

        ListNode *firstPtr;                   //  puntatore al primo nodo
ListNode *lastPtr;                    //  puntatore all' ultimo nodo
ListNode *getNewNode( const int& );   //  funzione che alloca memoria (facoltativa, per comodità)

};

#endif

Codice:

#ifndef LISTNODE_H
#define LISTNODE_H


class ListNode{

    friend class List;                 //  dichiaro la classe friend di List in modo che la classe List possa aver accesso ai dati memmnro privati di listNode

public:

ListNode( const int& );        //  costruttore con parametro un intero per inizializzare il dato membro
int getData( void ) const;     //  metodo get per recuperare il dato contenuto all' interno del nodo
void setData( int& );          //  metodo set per impostare il dato membro del nodo

    private:

int data;                      //  dato membro principale (può essere di qualunque tipo, anche una classe)
ListNode *nextPtr;             //  puntatore al nodo successivo, tipico della struttura ricorsiva (indispensabile)

};

#endif

Registrato
jSte75
Jr. Member
**

Karma: +4/-0
Scollegato Scollegato

Messaggi: 71


Mostra profilo
« Risposta #1 inserita:: Giugno 20, 2012, 03:01:25 pm »

Ciao,
ad uno sguardo veloce (mooolto veloce) direi che c'è un errore nel pezzo di codice:
Codice:
while( currentPtr != 0 ){

        if( currentPtr -> data > currentPtr -> nextPtr -> data ){
Il test del while non da' alcuna garanzia che currentPtr -> nextPtr sia valorizzato, quindi quando raggiungi la fine lista nextPtr è nullo e quindi si genera un errore.

Stefano
Registrato
jappoz92
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 8


Mostra profilo E-mail
« Risposta #2 inserita:: Giugno 20, 2012, 03:08:09 pm »

Intanto grazie della risposta, ho capito quello che vuoi dire, però se fosse così non mi darebbe l' errore alla fine del programma? (Io nel main dopo il metodo sort chiamo il metodo print per vedere la lista ordinata e a quel punto si blocca proprio il programma e windows mi da un errore.) Se fosse così almeno la lista fino a n - 1 me la dovrebbe far vedere no?
Secondo te come posso fare per ovviare a questa cosa?

Grazie ancora per l'attenzione, saluti Sorriso
Registrato
jappoz92
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 8


Mostra profilo E-mail
« Risposta #3 inserita:: Giugno 22, 2012, 02:13:10 pm »

Nessuna idea? Tra l' altro dovrei anche calcolarne la complessità che così a naso mi sembra O(n^2)...
Registrato
pancry777
Full Member
***

Karma: +20/-61
Scollegato Scollegato

Messaggi: 555


pancrazio.carbotti@hotmail.it
Mostra profilo
« Risposta #4 inserita:: Giugno 22, 2012, 02:21:22 pm »

 Felice tutte le strutture sequenziali come le liste, file ecc.. si ordinano solo con il merge sort
Registrato
jappoz92
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 8


Mostra profilo E-mail
« Risposta #5 inserita:: Giugno 22, 2012, 02:34:40 pm »

Nel esercizio del mio esame la consegna era di implementare una lista con vari metodi, di cui uno di sort a piacere e di calcolarne la complessità... forse te volevi dire che il migliore dal punto di vista computazionale è il merge sort?
Registrato
Roberto Allegra
Global Moderator
Hero Member
*****

Karma: +42/-1
Scollegato Scollegato

Messaggi: 2006



Mostra profilo WWW
« Risposta #6 inserita:: Giugno 22, 2012, 02:48:54 pm »

Citazione
Se fosse così almeno la lista fino a n - 1 me la dovrebbe far vedere no?

Direi di no: se la stampa la fai dopo l'ordinamento, l'errore avverrà prima del primo messaggio.

Il problema è molto probabilmente quello evidenziato da jSte75. Come ovviare è semplice: verifica anche che il successore non sia nullo, nella condizione di uscita del ciclo while. Il suggerimento è comunque di usare un debugger qualsiasi per verificare cosa succede durante l'esecuzione

La complessità computazionale è quella tipica del bubble sort, che viene spiegato - spesso per primo, dato che è semplice e notoriamente inefficiente - in tutti i testi di Algoritmi e Strutture dati. Studia bene come funziona, perché l'implementazione che hai realizzato nel codice è solo parziale.
Registrato

I moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.
jappoz92
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 8


Mostra profilo E-mail
« Risposta #7 inserita:: Giugno 22, 2012, 05:24:27 pm »

Grazie per l' aiuto, ho modificato il while come segue ed effettivamente ora non si blocca e stampa tutto
Codice:
while( ( currentPtr != 0 ) && ( currentPtr -> nextPtr != 0 ) )

C'è comunque ancora un problema che non riesco a identificare per il quale il metodo mi mette in ordine solo l' elemento più piccolo e il più grande ma gli altri non li scambia, è come se facesse solo un ciclo. Per esempio se io immetto nella lista
9 2 7 3 6 6 5 6
Chiamando il metodo sort e stampando la lista dopo mi restituisce una lista fatta così:
2 7 3 6 6 5 6 9

Ho controllato sul libro e mi sembra che il concetto (per quanto riguarda il bubblesort) sia giusto, non è un algoritmo per nulla complicato eppure mi sta dando diversi problemi.
Registrato
Roberto Allegra
Global Moderator
Hero Member
*****

Karma: +42/-1
Scollegato Scollegato

Messaggi: 2006



Mostra profilo WWW
« Risposta #8 inserita:: Giugno 23, 2012, 06:15:03 pm »

Citazione
Ho controllato sul libro e mi sembra che il concetto (per quanto riguarda il bubblesort) sia giusto, non è un algoritmo per nulla complicato eppure mi sta dando diversi problemi.

Come ti ho scritto, l'implementazione che hai fornito è solo parziale. Come hai già capito, il problema è che svolgi un solo "passaggio" di ordinamento, mentre il tutto dev'essere messo in un ciclo che continui finché non si verificano più scambi. Leggi bene l'implementazione del bubble sort, sul tuo libro di testo o su una qualunque fonte decente.
Registrato

I moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.
jappoz92
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 8


Mostra profilo E-mail
« Risposta #9 inserita:: Giugno 24, 2012, 12:06:41 pm »

Citazione
Ho controllato sul libro e mi sembra che il concetto (per quanto riguarda il bubblesort) sia giusto, non è un algoritmo per nulla complicato eppure mi sta dando diversi problemi.

Come ti ho scritto, l'implementazione che hai fornito è solo parziale. Come hai già capito, il problema è che svolgi un solo "passaggio" di ordinamento, mentre il tutto dev'essere messo in un ciclo che continui finché non si verificano più scambi. Leggi bene l'implementazione del bubble sort, sul tuo libro di testo o su una qualunque fonte decente.

Allora io so che il bubblesort di solito viene implementato (per gli array) con due cicli for. Il problema è che qua io ho una lista, e non so a priori quanto è grande questa lista essendo una struttura dinamica. Ho pensato di fare un secondo while più esterno, perchè il primo mi assicura solo un giro, però non saprei proprio quale condizione potrei inserire all' interno di questo secondo while...
Registrato
pancry777
Full Member
***

Karma: +20/-61
Scollegato Scollegato

Messaggi: 555


pancrazio.carbotti@hotmail.it
Mostra profilo
« Risposta #10 inserita:: Giugno 24, 2012, 01:57:42 pm »

metti una metodo che ti dice se è l'ultimo elemento della lista e lo fai di tipo boolean
Registrato
Roberto Allegra
Global Moderator
Hero Member
*****

Karma: +42/-1
Scollegato Scollegato

Messaggi: 2006



Mostra profilo WWW
« Risposta #11 inserita:: Giugno 24, 2012, 01:57:55 pm »

Non importa se siano vettori, liste, o quant'altro, né se la dimensione è nota o meno. Ripeto: il tutto dev'essere messo in un ciclo che continui finché non si verificano più scambi. Una volta detto questo l'implementazione è veramente banale. Rinnovo l'invito a leggere almeno lo pseudocodice dato da una qualunque fonte decente, perfino wikipedia italiana (che comunque, a quanto vedo, non si smentisce. Ci sono almeno tre strafalcioni, solo nella sezione che ho guardato...  Occhi al cielo).
Registrato

I moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.
jappoz92
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 8


Mostra profilo E-mail
« Risposta #12 inserita:: Giugno 24, 2012, 03:25:48 pm »

Intanto grazie per la pazienza e la disponibilità Roberto, però io proprio non ci arrivo anche se è una banalità. Ho capito quello che vuoi dire, ovvero che il ciclo deve continuare finchè si effettuano scambi, ma non saprei come mettere questa condizione in un while. Mi spiego meglio...
Col codice in questa forma
Codice:
while(  ){

    while( ( currentPtr != 0 ) && ( currentPtr -> nextPtr != 0 )){

        if( (currentPtr -> data) > (currentPtr -> nextPtr) -> data ){

            int aux = currentPtr -> data;
            currentPtr -> data = currentPtr -> nextPtr -> data;
            currentPtr -> nextPtr -> data = aux;

        }

     currentPtr = currentPtr -> nextPtr;

    }
 currentPtr = firstPtr;
}
return;

}
ho pensato di aggiungere un while più esterno (con argomento ignoto per adesso Sorriso ) che azzeri il puntatore in modo da scorrere sempre dall' inizio il ciclo. Quello che non capisco è come imporre la condizione che continui a farlo finchè scambia. Guiardando lo pseudocodice di wikipedia mi è venuto in mente di mettere il corpo dell' if all' interno di una funzione "scambio" che ritorni true se fa qualcosa e false se non fa niente, e in questo modo potrei scrivere
Codice:
while(scambio) ecc
però volevo cercare di capire come fare senza usare questo escamotage...
Registrato
Roberto Allegra
Global Moderator
Hero Member
*****

Karma: +42/-1
Scollegato Scollegato

Messaggi: 2006



Mostra profilo WWW
« Risposta #13 inserita:: Giugno 24, 2012, 04:55:13 pm »

Citazione
Guiardando lo pseudocodice di wikipedia mi è venuto in mente di mettere il corpo dell' if all' interno di una funzione "scambio" che ritorni true se fa qualcosa e false se non fa niente

Non serve una funzione: è sufficiente dichiarare una variabile booleana all'esterno del ciclo (tipo "bool haFinito"), che viene posta a true all'inizio del ciclo più interno e a false quando avviene uno scambio. Non è un escamotage: è l'implementazione più classica dell'algoritmo di bubble-sort. Poiché un'iterazione dev'essere fatta per forza, puoi usare un do..while(!haFinito).
Registrato

I moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.
jappoz92
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 8


Mostra profilo E-mail
« Risposta #14 inserita:: Giugno 24, 2012, 05:22:26 pm »

Citazione
Guiardando lo pseudocodice di wikipedia mi è venuto in mente di mettere il corpo dell' if all' interno di una funzione "scambio" che ritorni true se fa qualcosa e false se non fa niente

Non serve una funzione: è sufficiente dichiarare una variabile booleana all'esterno del ciclo (tipo "bool haFinito"), che viene posta a true all'inizio del ciclo più interno e a false quando avviene uno scambio. Non è un escamotage: è l'implementazione più classica dell'algoritmo di bubble-sort. Poiché un'iterazione dev'essere fatta per forza, puoi usare un do..while(!haFinito).

Eureka finalmente mi funziona! Sorriso
Grazie mille ancora, per dovere di cronaca posto il codice finale... magari un domani potrebbe servire a qualcuno

Codice:
void List::Sort( void ){

    bool fine;

    if( IsEmpty() ){

cout << "Lista VUOTA" << endl;
return;

}

    ListNode *currentPtr = firstPtr;

 do{

    fine = true;
    while( ( currentPtr != 0 ) && ( currentPtr -> nextPtr != 0 )){



        if( (currentPtr -> data) > (currentPtr -> nextPtr) -> data ){

            int aux = currentPtr -> data;
            currentPtr -> data = currentPtr -> nextPtr -> data;
            currentPtr -> nextPtr -> data = aux;
            fine = false;

        }

     currentPtr = currentPtr -> nextPtr;

    }

 currentPtr = firstPtr;

 }while(!fine);

return;

}



 
Registrato
Pagine: [1]   Vai su
  Stampa  
 
Vai a:  

Copyright © 2011 Edizioni Master SpA. p.iva : 02105820787

Tutti i diritti di proprietà letteraria e artistica riservati. - Privacy



Links to Page