/* semplici primitive di gestione di una lista ordinata (numerica)
* tramite rappresentazione concatenata */
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#include"lista.h"
struct nodo_lista {
type_lista elemento;
struct nodo_lista *next;
};
/* prototipi funzioni ad uso interno */
void districorsLISTA(struct nodo_lista *);
struct nodo_lista *punto_di_inserzione(struct nodo_lista *, type_lista);
static struct nodo_lista *testa=NULL;
static int numelementi=0;
/* crea la lista di dimensione massima fornita
* ritorna OK o ERR */
int creaLISTA(int numel){
if((testa=malloc(sizeof(struct nodo_lista)))==NULL)
return LISTA_ERR;
testa->elemento=-INT_MAX;
testa->next=NULL;
numelementi=0;
return LISTA_OK;
}
/* distrugge la lista si appoggia ad una funzione
* ricorsiva */
void destroyLISTA(void){
if(testa)
districorsLISTA(testa);
numelementi=0;
}
/* funzione interna di liberazione ricorsiva memoria */
void districorsLISTA(struct nodo_lista *a){
if(!a->next)
districorsLISTA(a->next);
free(a);
}
/* ritorna numero elementi lista */
int elementiinLISTA(void){
return numelementi;
}
/* inserisce elemento in lista ritorna OK o ERR
* ancora una volta mi appoggio ad una funzione ricorsiva esterna */
int inserisciinLISTA(type_lista a){
struct nodo_lista *nuovo, *p;
int jj;
/* attenzione! non tengo conto del massimo
* numero di valori */
/* controllo la presenza in lista */
if((trovainLISTA(a, &jj))==LISTA_OK)
return LISTA_ERR;
++numelementi;
/* alloco nuovo nodo */
if((nuovo=malloc(sizeof(struct nodo_lista)))==NULL)
return LISTA_ERR;
/* metto i dati */
nuovo->elemento=a;
nuovo->next=NULL;
/* ricerco punto di inserzione */
p=punto_di_inserzione(testa, a);
nuovo->next=p->next;
p->next=nuovo;
return LISTA_OK;
}
/* scorre la lista e restituisce il punto in cui inserire il dato */
struct nodo_lista *punto_di_inserzione(struct nodo_lista *start, type_lista valore){
if(!start->next)return start; /* sicuramente inserisco qui se sono in fondo */
if(start->next->elemento>valore)return start;
return punto_di_inserzione(start->next,valore);
}
/* ricerca l'elemento ne ritorna l'indice e l'esito
* dell'operazione */
int trovainLISTA(type_lista a, int* index){
int counter=0;
struct nodo_lista *ii;
for(ii=testa->next;ii;ii=ii->next){
if(ii->elemento==a){
*index=counter;
return LISTA_OK;
}
++counter;
}
return LISTA_ERR;
}
/* rimuove l'elemento in funzione dell'indice
* e ritorna l'esito */
int rimuovidaLISTA(int indice){
int counter;
struct nodo_lista *ii, *p;
/* controllo il valore dell'indice */
if((indice>numelementi)||(indice<0))
return LISTA_ERR;
counter=1;
for(ii=testa->next;counter<indice;ii=ii->next)
++counter;
/* ii contiene l'elemento precedente
* a quello che si vuole eliminare */
p=ii->next;
/* cambio i collegamenti */
ii->next=ii->next->next;
free(p);
--numelementi;
return LISTA_OK;
}
/* recupera l'elemento in funzione dell'indice
* ritorna lo stato dell'operazione */
int indiceLISTA(int indice,type_lista *a){
int counter;
struct nodo_lista *ii;
/* controllo il valore dell'indice */
if((indice>numelementi)||(indice<0))
return LISTA_ERR;
counter=0;
for(ii=testa->next;counter!=indice;ii=ii->next)
++counter;
/* ii punta al nodo di indice voluto */
*a=ii->elemento;
return LISTA_OK;
}
/* inverte l'ordine della lista */
void invertiLISTA(void){
struct nodo_lista *t, *y, *r;
if(numelementi<=1)
return;
/*ignoro la testa fasulla*/
y=testa->next;
r=NULL;
while(y!=NULL){
t=y->next;
y->next=r;
r=y;
y=t;
}
testa->next=r;
}