Newsgroup: it.comp.lang.c
Titolo: confronto campi lista

Ciao a tutti, ho il seguente problema enon sono riuscito a risolverlo,ho
una lista di cui voglio scandire gli elementi per togliere quelli che , in
base ad un operazione(la differenza tra le ascisse e le ordinate del nodo
e di un punto)mi risultano essere i piu' lontani dal punto stesso, e
tenere solo quelli con la distanza minore. 
i nodi lista hanno un campo int dist,x,y; e testa punta all inizio della
lista, x e y sono le 2 coordinate: 
void min(void){  /*confronto tra campi interi di una lista*/ 
nodo *p; 
for(p = head; p!=NULL; p = p->next){/*testa punta al 1 elemento*/ 
do { 
if (p->dist > p->next->dist) 
head = elimina(head,p);    /*elimina il nodo*/ 
else if (p->dist < p->next->dist) 
head = elimina(head,p->next); 
} while (p->next!=NULL); 
} 
} 
scusate la domanda forse stupida ma non capisco come mai non funziona.
Grazie in anticipo
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 Ciao a tutti, ho il seguente problema enon sono riuscito a risolverlo,ho
Ma questo codice non vuol dire nulla!
Sembra che scandisci la lista eliminando, di due elementi
adiacenti, quello con la distanza maggiore.
(Gia' questo sembra diverso da quello che avevi detto a parole).
Poi invochi una sconosciuta routine "elimina" che potrebbe
andare ad eliminare proprio il record che nel
ciclo successivo del for vai a seguire. Per forza
che non funziona.
Non posso neanche aiutarti perche' non ti sei spiegato.
L'unico consiglio che posso darti e'
di metterti con pazienza a scrivere l'algoritmo
in "italiano" descrivendo tutti i passi.
Puoi benissimo fare a meno di invocare la routine elimina,
visto che eliminare un record sul quale sei praticamente
posizionato non richiede una scansione totale della lista.
Dopo tradurlo in  C dovrebbe essere facile.
ciao,
g.

 che non funziona.
ehhmmm... hai completamente ragione,ma "elimina" mi collega comunque il
nodo precedente a quello successivo del nodo cancellato, quindi
pensavo(male) che andasse bene lo stesso.
qundi magari utilizzo un altra lista dove copio gli elementi che mi
interessano? cosi non cado nel fatto di cancellare un elemento su cui sono
posizionato durante il for..
grazie per l' aiuto!


 tenere solo quelli che hanno il valore minore nel campo dist.
Valore minore di cosa ?
Se vuoi tenere solo i record che hanno il valore minore
(per esempio supponendo che il valore minore presente sia 117,
tutti quelli che hanno dist=117)
allora la cosa piu' semplice (a questo livello parliamo di semplicita'
del codice, non di prestazioni) e'
1) scandisci tutta la lista per cercare quale e' il valore
minimo per dist
2) scandisci tutta la lista, copiando in una nuova lista
    solo i record che hanno il valore dist uguale al minimo
trovato prima
3) cancelli (se necessario) la lista originaria.
Se dividi il lavoro in questi 3 passi semplicissimi e' impossibile
sbagliare.
ciao,
g.

 3) cancelli (se necessario) la lista originaria.
ti ringrazio molto per la tua pazienza, faro cosi come dici, ma per
curiosita', proprio in 2 parole, cosa sarebbe meglio a livello
prestazionale?
Grazie
ciao


 prestazionale?
Mah. dipende da quanti record hai complessivi, da quanto sono grandi
e da quale percentuale di record con il valore minimo ci sono.
In certi casi puo' anche convenire farsi una propria gestione
della memoria (niente di particolarmente sofisticato) per evitare
continui free e malloc di record.
Poi bisognerebbe vedere se ha senso ottimizzare. Se devi maneggiare 
qualche centinaio di record lungi qualche centinaio di byte non
vale troppo la pena addannarsi per risparmiare qualche millisecondo...
Comunque nel tuo caso potresti anche  fare una passata sola.
Naturalmente la cosa va fatta con un po' di
attenzione.
Infatti se i primi valori nella lista sono tutti uguali a 15
e l'ultimo vale 13 dovro' "cancellare" tutto il lavoro che ho fatto
e tenere solo il record 13.
Questo puo' comunque essere fatto abbastanza agevolmente:
poni di avere una newhead che puntera' al primo record
della nuova lista. E p che punta al record corrente da
esaminare.
In pratica mantieni una lista che e' fatta cosi':
R (dist=min)->
R (dist=min)->
....
R(dist=min)->
(p = )
record da trattare ->
record da trattare
...
cioe' assumi che la prima tranche della lista che stai
considerando (da newhead fino a p) sia composta
di record minimi. Inizialmente il primo record, qualunque
sia la sua dist soddisfa la proprieta' di essere quello
minimo visto fino a quel momento.
Quando esemini un nuovo elemento (quello puntato da p)
ci sono 3 possibilita'
1) dist e' maggiore del valore minimo
corrente. Allora cancelli il record corrente e lo
bypassi in modo che la lista dei minimi (e p) puntino
al successivo da esaminare
2) e' uguale. Allora fai semplicemente avanzare p, il che
corrisponde a "tenere" il record corrente
3) e' minore. Allora tutto il lavoro fatto fino ad ora
va buttato. In pratica cancelli tutti i record tra il newhead
e il record prima di quello corrente e poi metti come newhead
il record corrente e fai avanzare p.
e' piu' facile a farsi che a spiegarsi,
ciao,
g.

 ciao,
grazie ancora!
