Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Salve a tutti, utenti e moderatori del Forum. Chiedo aiuto nella soluzione di un semplice problema. Si tratta di stampare in uscita una lista di interi ordinata in senso crescente, a partire da una lista data in ingresso, costituita da numeri interi tutti diversi tra loro. La soluzione che ho elaborato, per quel che riguarda la procedura di calcolo della lista ordinata di cui sopra, fa uso di due cicli while, l'uno annidato nell'altro, con il più interno che confronta via, via, i singoli elementi della lista con gli n,n-1,...,1 elementi successivi, per determinare i massimi che verranno inseriti in testa alla lista ordinata dal più grande al più piccolo.Tuttavia tale soluzione, quando vado ad eseguire il programma risolutivo da me elaborato, mi dà errore 216. Credo che ciò sia dovuto al fatto che nel ciclo più interno di questa procedura il ciclo while tenta l'accesso a valori di p=nil. Qualcuno tra voi è in grado di indicarmi la soluzione esatta, e segnalarmi eventuali errori? Riporto di seguito il codice del programma che ho compilato:
Codice sorgente - presumibilmente Delphi
program ListaOrdinataInSensoCrescente(input,output);
const bell=07;
type punt=^elem;
elem=record
val:integer;
next : punt;
end;
var p,lista : punt;
n,max,risposta :integer;
procedure LeggiLista(var p : punt; k :integer);
begin
if k=0
then p:=nil
elsebegin
new(p);
read(p^.val);
LeggiLista(p^.next,k-1);
end;
end;{fine procedura LeggiLista}
procedure OrdinamentoLista(var p,lista : punt);
begin
{creo la lista degli elementi ordinati}
new(lista);
{il primo elemento di tale lista lo pongo uguale al primo della lista p
ed eventualmente se non è il più grande di p lo aggiornerò}
lista^.val:=p^.val;
while p<>nil
dobegin
{inizializzazione del valore del massimo della lista in ingresso}
p^.val:=max;
p:=p^.next;
{confronto via via degli elementi di p con tutti i loro successivi
e aggiornamento della variabile max}
while p<>nil
dobegin
if p^.val>max
thenmax:=p^.val;
p:=p^.next;
end;
{inserimento dell'elemento max ( che è il più grande via via tra gli n,n-1,..,1
elementi di p ) in testa alla lista ordinata così in senso crescente}
lista^.val:=max;
{aggionamento dell'elemento lista}
lista:=lista^.next;
{aggiornamento di p}
p:=p^.next;
end;
end;{fine procedura OrdinamentoLista}
{corpo del programma}
begin
repeat
writeln('--------------------------- Dati di ingresso --------------------------------');
writeln;
writeln;
write('Fornire la dimensione della lista: ');
readln(n);
if n>20
thenbegin
writeln(chr(bell),'Errore nei dati di ingresso! - STOP -');
exit;
end
elsebegin
writeln;
writeln;
writeln('Fornire la lista in ingresso:');
writeln;
writeln;
LeggiLista(p,n);
writeln;
writeln;
OrdinamentoLista(p,lista);
writeln;
writeln;
while(lista<>nil)
dobegin
write(lista^.val:3,' ');
lista:=lista^.next;
end;
end;
writeln;
writeln('Finito?');
writeln;
writeln;
writeln('Scrivere 1 per terminare 2 per continuare');
writeln;
writeln;
readln(risposta);
until(risposta=1);
readln;
end.
Ringraziando da ora chiunque saprà fornirmi la soluzione corretta vi saluto tutti. Ciao!!!
Ti ringrazio per il suggerimento. Ma io vorrei sapere se qualcuno di voi è in grado di segnalarmi l'errore nella procedura OrdinamentoLista. Forse va introdotta una variabile ausiliaria in modo da non incorrere nella chiamata di p=nil nel ciclo while più interno? E se sì, potresti formulare la risposta corretta in codice? Te ne sarei infinitamente grato...
intanto correggi la funzione LeggiLista come ti ho detto, perche' con quella che hai fatto tu ti ritrovi i valori dei p^.Next tutti sballati, e questo ti impedisce il corretto funzionamento della lista
Inoltre vedo ora che nella procedura di ordinamento fai per tutti e due i cicli innestati il controllo sulla stessa variabile (p), e gia' questa e' una cosa da non fare mai, poi noto che il metodo che usi per 'ordinamento e' totalmente sbagliato, non so che metodo avevi intenzione di implementare, ma sicuramente il codice che hai usato non funziona per niente, ti consiglio di riguardarti un po' di algoritmi di ordinamento.
poichè una volta individuato il valore di max per i vari n,n-1,..,1 elementi,questo vada via via estratto dalla lista di partenza p e posto in testa a lista e per questo credo sia necessario introdurre una variabile puntatore ausiliaria...
O.K., hai perfettamente ragione. Non mi ero reso conto della gravità dell'errore; cercherò di seguire i tuoi consigli e riscrivere completamente la procedura OrdinamentoLista...Grazie comunque!!!
Ho provato a riscrivere la procedura OrdinamentoLista. Tuttavia incontro due difficoltà : a) L'estrazione dei vari massimi via via decrescenti, dalla lista p ed il loro inserimento nella variabile 'lista'.
b) l'uso di un'altra variabile q per rappresentare la lista data in ingresso,nel ciclo while più interno.
Il codice del programma, che tuttavia così com'è non funziona, tenuto conto anche dei suggerimenti proposti è il seguente:
Codice sorgente - presumibilmente Delphi
program ListaCrescente(input,output);
const bell=07;
type punt=^elem;
elem=record
val:integer;
next : punt;
end;
var p,lista : punt;
n,max,risposta :integer;
Function LeggiLista(k :integer): punt;
var p : punt ;
begin
if k=0
then p:=nil
elsebegin
new(p);
read(p^.val);
p^.Next:= LeggiLista(k-1);
end;
LeggiLista := p;
end;{fine function LeggiLista}
procedure OrdinamentoLista(var p,lista : punt);
var q : punt;
begin
{creo la lista degli elementi ordinati}
new(lista);
{il primo elemento di tale lista lo pongo uguale al primo della lista p
ed eventualmente se non è il più grande di p lo aggiornerò}
lista^.val:=p^.val;
while p<>nil
dobegin
{inizializzazione del valore del massimo della lista in ingresso}
p^.val:=max;
p:=p^.next;
q:=p;
{confronto via via degli elementi di p con tutti i loro successivi
e aggiornamento della variabile max}
while q<>nil
dobegin
if q^.val>max
thenmax:=q^.val;
q:=q^.next;
end;
{inserimento dell'elemento max ( che è il più grande via via tra gli n,n-1,..,1
elementi di p ) in testa alla lista ordinata così in senso crescente}
lista^.val:=max;
{aggionamento dell'elemento lista}
lista:=lista^.next;
{aggiornamento di p}
p:=p^.next;
end;
end;{fine procedura OrdinamentoLista}
{corpo del programma}
begin
repeat
writeln('--------------------------- Dati di ingresso --------------------------------');
writeln;
writeln;
write('Fornire la dimensione della lista: ');
readln(n);
if n>20
thenbegin
writeln(chr(bell),'Errore nei dati di ingresso! - STOP -');
exit;
end
elsebegin
writeln;
writeln;
writeln('Fornire la lista in ingresso:');
writeln;
writeln;
p:=LeggiLista(n);
writeln;
writeln;
OrdinamentoLista(p,lista);
writeln;
writeln;
while(lista<>nil)
dobegin
write(lista^.val:3,' ');
lista:=lista^.next;
end;
end;
writeln;
writeln('Finito?');
writeln;
writeln;
writeln('Scrivere 1 per terminare 2 per continuare');
writeln;
writeln;
readln(risposta);
until(risposta=1);
readln;
end.
Sarò grato da ora a chiunque sia in grado di fornirmi la versione corretta della procedura OrdinamentoLista. Ciao a tutti!!!
tu che vuoi fare?
Ordinare la lista che hai?
Oppure creare una copia ordinata della lista, lasciando l'originale inalterata (e quindi disordinata)?
perche' nel primo caso, non ha senso che nella OrdinamentoLista tu ne crei un'altra;
nel secondo caso invece l'approccio che usi e' sbagliato, per esempio, su quali basi come prima istruzione fai questa assegnazione?
Codice sorgente - presumibilmente Plain Text
lista^.val:=p^.val;
e poi alla prima iterazione del ciclo l'assegnazione
Codice sorgente - presumibilmente Plain Text
p^.val:=max;
dove vai a modificare il primo elemento della lista originale (p) con un valore (max) che ancora non e' stato definito
ti do un suggerimento funzionale (cioe' ti dico a parole i passi da eseguire, poi pero' devi essere tu a tradurlo in codice)
Caso 1: Ordinamento della lista originale
Passo 1: dichiari tre variabili di tipo punt per scorrere la lista (chiamiamole per esempio Idx, Min, e RelStart);
Passo2: assegni a RelStart il puntatore al primo elemento;
Passo 3: Inizio ciclo esterno, con condizione di uscita quando RelStart^.Next punta a Nil;
Passo 4: Ciclo interno in cui, col puntatore Idx scorri la lista alla ricerca dell'elemento col valore minimo, all'uscita del ciclo memorizzerai in Min il puntatore all'elemento col valore minimo;
Passo 5: uscito dal ciclo interno, scambi i valori degli elementi puntati da Min e da RelStart;
Passo 6: fai puntare RelStart all'elemento successivo;
Passo 7: Fine ciclo esterno, ritorna al passo 3, se non si verifica la condizione di uscita;
Caso 2: Creazione di una copia ordinata della lista
Passo 1: dichiari una variabile di tipo punt per scorrere la lista originale (chiamiamola per esempio Idx)
piu' altre due, sempre di tipo punt, per scorrere la nuova lista (chiamiamole per esempio IdxCopy e PrecIdxCopy);
Passo 2: inserisci nella nuova lista un elemento che avra' il valore del primo elemento della lista originale, inoltre fai puntare Idx all'elemento successivo al primo della lista originale;
Passo 3: Inizio ciclo esterno, con condizione di uscita quando Idx punta a Nil;
Passo 4: fai puntare IdxCopy al primo elemento della nuova lista;
Passo 5: Inizio ciclo interno, con condizione di uscita quando Il valore dell'elemento puntato da IdxCopy e' maggiore dell'elemento puntato da Idx;
Passo 6: finche' resti nel ciclo, ad ogni iterazione, fai puntare PrecIdxCopy all'elemento puntato da IdxCopy e poi fai puntare IdxCopy all'elemento successivo;
Passo 7: uscito dal ciclo interno, dovrai inserire un nuovo elemento (per esempio NewEl) nella nuova lista, che dovra' essere posizionato tra PrecIdxCopy e IdxCopy ( in pratica PrecIdxCopy^.Next dovra' puntare a NewEl, e NewEl^.Next dovra' puntare a IdxCopy)
Passo 8: fai puntare Idx all'elemento successivo;
Passo 9: Fine ciclo esterno, ritorna al passo 3, se non si verifica la condizione di uscita;
PS Ovviamente, se non ti scrivo il codice (per il quale avrei, tra l'altro, impiegato meno tempo), non e' per cattiveria, ma solo perche' soltanto facendolo tu da solo puoi sperare di imparare qualcosa di programmazione
Gentile GigiSoft, so che mi hai già invitato a sviluppare il programma da solo ma, come forse avrai intuito, sto studiando il linguaggio Pascal da completo autodidatta, e trovo notevoli difficoltà con i puntatori e le liste, perciò provo a chiederti lo stesso se puoi essere così gentile da fornirmi la soluzione in codice sorgente poichè io non riesco ad elaborarla da solo. Mi sarebbe infinitamente utile per progredire nello studio degli ordinamenti nelle liste. Grazie infinitamente fino da ora se vorrai aiutarmi. Ciao!!!