diff --git a/Makefile b/Makefile index f6c09837b350bcbd2100eb1ce4670d37a82cff45..8c86565efcf0f05d3af894f5e5dd2ccc33eec4a6 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ test: main chmod +x runTests.sh; \ ./runTests.sh -main: main.c tabuleiro.o filha.o no.o +main: main.c tabuleiro.o filha.o lista.o no.o $(CC) $(CFLAGS) -o $@ $^ clean: diff --git a/lista.c b/lista.c new file mode 100644 index 0000000000000000000000000000000000000000..bea275b79ebb30ee846f43c4a3caf15d28c2ff7c --- /dev/null +++ b/lista.c @@ -0,0 +1,121 @@ +#include <malloc.h> +#include "lista.h" +#include "no.h" +//--------------------------------------------------------------------------- +// Lista encadeada + +struct Lista { + + unsigned int tamanho; + int padding; // só pra evitar warning + No primeiro; +}; +//--------------------------------------------------------------------------- +// devolve o número de nós da Lista l + +unsigned int tamanhoLista(Lista l) { return l->tamanho; } + +//--------------------------------------------------------------------------- +// devolve o primeiro nó da Lista l, +// ou NULL, se l é vazia + +No primeiroNoLista(Lista l) { return l->primeiro; } + +//--------------------------------------------------------------------------- +// cria uma Lista vazia e a devolve +// +// devolve NULL em caso de falha + +Lista constroiLista(void) { + + Lista l = malloc(sizeof(struct Lista)); + + if ( ! l ) + return NULL; + + l->primeiro = NULL; + l->tamanho = 0; + + return l; +} +//--------------------------------------------------------------------------- +// desaloca a Lista l e todos os seus nós +// +// se destroi != NULL invoca +// +// destroi(getConteudo(n)) +// +// para cada nó n da Lista. +// +// devolve 1 em caso de sucesso, +// ou 0 em caso de falha + +int destroiLista(Lista l, int destroi(void *)) { + + No p; + int ok=1; + + while ( (p = primeiroNoLista(l)) ) { + + l->primeiro = getSucessorNo(p); + + if ( destroi ) + ok &= destroi(getConteudo(p)); + + free(p); + } + + free(l); + + return ok; +} +//--------------------------------------------------------------------------- +// insere um novo nó na Lista l cujo conteúdo é p +// +// devolve o No recém-criado +// ou NULL em caso de falha + +No insereLista(void *conteudo, Lista l) { + + No novo = criaNo(); + + if ( ! novo ) + return NULL; + + setConteudo(novo, conteudo); + setSucessorNo(novo, primeiroNoLista(l)); + ++l->tamanho; + + return l->primeiro = novo; +} + +//------------------------------------------------------------------------------ +// remove o No de endereço rNo de l +// se destroi != NULL, executa destroi(getConteudo(rNo)) +// devolve 1, em caso de sucesso +// 0, se rNo não for um No de l + +int removeNo(struct Lista *l, struct No *rNo, int destroi(void *)) { + int r = 1; + if (l->primeiro == rNo) { + l->primeiro = getSucessorNo(rNo); + if (destroi != NULL) { + r = destroi(getConteudo(rNo)); + } + free(rNo); + l->tamanho--; + return r; + } + for (No n = primeiroNoLista(l); getSucessorNo(n); n = getSucessorNo(n)) { + if (getSucessorNo(n) == rNo) { + setSucessorNo(n, getSucessorNo(rNo)); + if (destroi != NULL) { + r = destroi(getConteudo(rNo)); + } + free(rNo); + l->tamanho--; + return r; + } + } + return 0; +} diff --git a/lista.h b/lista.h new file mode 100644 index 0000000000000000000000000000000000000000..2056e1a479b4a6d520db14cfb45e7fde4b0b60c6 --- /dev/null +++ b/lista.h @@ -0,0 +1,55 @@ +#ifndef _LISTA_ +#define _LISTA_ +#include "no.h" + +//----------------------------------------------------------------------------- +// (apontador para) Lista encadeada + +typedef struct Lista *Lista; + +//------------------------------------------------------------------------------ +// devolve o número de nós da Lista l + +unsigned int tamanhoLista(Lista l); + +//------------------------------------------------------------------------------ +// devolve o primeiro nó da Lista l, +// ou NULL, se l é vazia + +No primeiroNoLista(Lista l); + +//------------------------------------------------------------------------------ +// insere um Novo nó na Lista l cujo conteúdo é p +// +// devolve o No recém-criado +// ou NULL em caso de falha + +No insereLista(void *conteudo, Lista l); +//------------------------------------------------------------------------------ +// cria uma Lista vazia e a devolve +// +// devolve NULL em caso de falha + +Lista constroiLista(void); +//------------------------------------------------------------------------------ +// desaloca a Lista l e todos os seus nós +// +// se destroi != NULL invoca +// +// destroi(conteudo(n)) +// +// para cada nó n da Lista. +// +// devolve 1 em caso de sucesso, +// ou 0 em caso de falha + +int destroiLista(Lista l, int destroi(void *)); + +//------------------------------------------------------------------------------ +// remove o No de endereço rNo de l +// se destroi != NULL, executa destroi(conteudo(rNo)) +// devolve 1, em caso de sucesso +// 0, se rNo não for um No de l + +int removeNoLista(struct Lista *l, struct No *rNo, int destroi(void *)); +#endif