Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da...
Transcript of Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da...
![Page 1: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/1.jpg)
1
Listas Encadeadas
![Page 2: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/2.jpg)
2
Listas Seqüenciais
Conjunto de itens organizados vetor– a organização é implícita (pela posição)
– o símbolo vet representa o endereço do primeiro elemento (ponteiro)
– ocupa um espaço contíguo na memória:permite acesso a qualquer elemento a partir
do ponteiro para o primeiro, utilizando indexação acesso aleatório
vet
A L I TS
![Page 3: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/3.jpg)
3
Listas Seqüenciais
Qual a principal desvantagem de se usar o armazenamento seqüencial para representar Listas?
Quantidade fixa de elementos– memória alocada sem uso ou– impossibilidade de alocar mais
memória
![Page 4: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/4.jpg)
4
Listas Lineares
Solução?
Listas Encadeadas
Utilizar Estruturas de Dados que cresçam e diminuam na medida da necessidade Estruturas Dinâmicas
Alocação dinâmica de memória para armazenar os elementos
![Page 5: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/5.jpg)
5
Listas Encadeadas
Podem crescer e diminuir dinamicamenteTamanho máximo não precisa ser
definido previamente Provêem flexibilidade, permitindo que os
itens sejam rearrumados eficientemente– perda no tempo de acesso a qualquer item
arbitrário da lista, comparando com vetores
Também chamadas de Listas Ligadas
![Page 6: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/6.jpg)
6 A L I TS
Listas Encadeadas A seqüência de elementos é especificada
explicitamente, onde cada um contém um ponteiro para o próximo da lista (link) Encadeamento
Cada elemento é chamado de nó da lista A lista é representada por um ponteiro para o
primeiro elemento (ou nó) Do primeiro elemento, pode-se alcançar o segundo
seguindo o encadeamento e assim sucessivamente Para cada novo elemento inserido na estrutura, um
espaço na memória é alocado dinamicamente, mas a alocação do espaço não é contígua
lista
![Page 7: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/7.jpg)
7
Listas Encadeadas
Detalhes que devem ser considerados:– cada elemento possui pelo menos dois campos:
um para armazenar a informação e outro para o endereço do próximo (ponteiro)
– deve haver um ponteiro especial para o 1O da lista
– o ponteiro do último elemento tem que especificar algum tipo de final (aponta para si próprio ou nulo)
– uma lista vazia (ou nula) é uma lista sem nósA
lista info prox
L I S T
nó
![Page 8: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/8.jpg)
8
Listas Encadeadas
Algumas operações são mais eficientes do que em Lista Seqüencial– Mover o elemento com a informação T do fim
da lista para o início– Mesmo que a lista seja muito longa, a
mudança estrutural é realizada através de 3 operações
A
lista
L I S T
![Page 9: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/9.jpg)
9
Listas Encadeadas
Para inserção de um novo elemento X: – aloca-se memória para um elemento e
atualiza-se os ponteiros– em lista seqüencial seria necessário deslocar
todos os elementos a partir do ponto de inserção;
– apenas 2 links são alterados para esta operação - não importa quão longa é a lista
A
lista
L I S T
X
![Page 10: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/10.jpg)
10
Remoção de um elemento:– Basta alterar o ponteiro do elemento
anterior ao removido
– o conteúdo de I (no exemplo) ainda existe, mas não é mais acessível pela lista
Listas Encadeadas
A
lista
L I S T
![Page 11: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/11.jpg)
11
Listas Encadeadas
Lista Encadeada x Seqüencial– remoção e inserção são mais naturais na
lista encadeada– outras operações já não são tão naturais
Encontrar o k-ésimo elemento da lista – em uma lista seqüencial - simplesmente acessar
a[k-1] – na lista encadeada é necessário percorrer k links
Achar um item localizado antes de um outro item
![Page 12: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/12.jpg)
12
Listas Encadeadas
Duplamente encadeada - ponteiros para duas direções – um ponteiro para o próximo e um para o anterior
Simplesmente encadeada - ponteiros em uma direção
![Page 13: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/13.jpg)
13
Listas Encadeadas
Implementações:typedef int tpitem;
typedef struct tp_no { tpitem info; struct tp_no *prox;
} tplista; tplista *lista;
![Page 14: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/14.jpg)
14
Listas Encadeadas
Inicialização da Lista:lista=NULL;
Lista Vazia:int vazia (tplista *t) {
return (t==NULL);
}
![Page 15: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/15.jpg)
15
Listas Encadeadas
Alocação Dinâmica de Memória – malloc aloca( );– free – exigem #include "stdlib.h"
![Page 16: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/16.jpg)
16
Manipulação da Memória
Função malloc– aloca dinamicamente uma parte da
memória– recebe como parâmetro o número de
bytes que se deseja alocar– retorna um ponteiro para endereço inicial
da área alocada– se não houver espaço livre, retorna um
endereço nulo (representado por NULL, definido em stdlib.h) que pode ser testado para encerrar o programa
![Page 17: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/17.jpg)
17
Manipulação da Memória
Função malloc– Ex.:
int *p;
p = malloc(8);
– p representa o endereço inicial de uma área contínua de memória suficiente para armazenar 8 bytes
![Page 18: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/18.jpg)
18
Manipulação da Memória
Função malloc– utilização da função sizeof( )
int *p;p = malloc(sizeof(int));
– ponteiro retornado é para um item do tipo char converter o tipo (cast)int *p;p = (int *) malloc(sizeof(int));
código do programa
variáveis globais e estáticas
p
504
504
4 bytes
Livre
![Page 19: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/19.jpg)
19
Manipulação da Memória
aloca()
tplista* aloca( ) {tplista* pt;pt=(tplista*) malloc(sizeof(tplista));return pt;
}
No bloco principal:p=aloca( );if (p!=NULL)
/* continua o programa... */else
printf(“Não há memória disponível!”);
![Page 20: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/20.jpg)
20
Manipulação da Memória
Função free
– Libera o espaço de memória alocado dinamicamente
– recebe como parâmetro o ponteiro da área de memória a ser liberada
– Ex.: free(p);
![Page 21: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/21.jpg)
21
Listas Encadeadas
Operações Básicas– vazia(lista);– insere(&lista, valor);– busca(lista, valor);– listagem(lista);– retira(&lista, valor);
![Page 22: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/22.jpg)
22
Lista Vazia
int vazia (tplista *t) { if (t==NULL)
return 1;
elsereturn 0;
}
![Page 23: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/23.jpg)
23
Listagem
Utilizar um ponteiro auxiliar para percorrer a lista até o final
t
p p p pp
![Page 24: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/24.jpg)
24
Listagem
void listagem (tplista *t) {
tplista *p;
for (p=t; p!=NULL; p=p->prox)
printf("Info: %d\n", p->info);
}
![Page 25: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/25.jpg)
25
Busca
Utilizar um ponteiro auxiliar para percorrer a lista até encontrar ou até chegar ao final
A função retorna o ponteiro para o elemento ou NULL caso não encontre
![Page 26: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/26.jpg)
26
Busca
tplista* busca (tplista *t , tpitem valor) {
tplista *p=t;
while ((p!=NULL) && (p->info!=valor))
p=p->prox;
return p;
}
![Page 27: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/27.jpg)
27
Inserção no Início
Cada elemento armazena uma informação do tipo tp_item
A função:– recebe como parâmetros um ponteiro
para a lista e o novo elemento– tenta alocar dinamicamente o espaço
para o novo nó, guardando a informação e fazendo ele apontar para o início da lista
– retorna o novo ponteiro da lista ou NULL caso não seja possível incluir
![Page 28: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/28.jpg)
28
Inserção no Início
Estrutura usada:
typedef int tpitem;
typedef struct tp_no {
tpitem info;struct tp_no *prox;
} tplista;
tplista * lista;
t
![Page 29: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/29.jpg)
29
Inserção no Início
tplista * insere (tplista *t , tpitem valor) {tplista *novo;novo = aloca( );if (!novo)
return(NULL);else {
novo->info = valor;novo->prox = t;return(novo);
}}
Insere em qualquer lista, retornando um ponteiro para o primeiro. Quem chama a função deve atualizar o ponteiro da lista com o valor retornado:
tmp= insere(lista,12); if (tmp) lista=tmp; else
printf(“Sem memória”);
![Page 30: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/30.jpg)
30
Inserção no Início (Por referência)
int insere (tplista **t , tpitem valor) {tplista *novo;novo = aloca( );if (!novo) return 0;else {novo->info = valor;novo->prox = *t;*t=novo;return 1;}
}
Insere em qualquer lista, retornando 1 ou zero
para indicar sucesso ou falta de memória. A função já atualiza
automaticamente o ponteiro de início da
lista.
ok= insere(&lista,12); if (!ok)
printf(“Sem memória”);
![Page 31: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/31.jpg)
31
Inserção Geral
Insere elementos em uma lista classificada, mantendo a ordenação
Ponto chave: localizar o elemento da lista que precede o novo
De posse do ponteiro para este antecessor, pode-se encadear o novo elemento:– o novo apontará para o próximo do
antecessor– o antecessor apontará para o novo
![Page 32: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/32.jpg)
32
Inserção Geral
Estrutura usada:
typedef int tpitem;
typedef struct tp_no {
tpitem info;struct tp_no *prox;
} tplista;
tplista * lista;
t
B E
G
M R
![Page 33: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/33.jpg)
/* procura posição do elemento */while (p!=NULL && p->info < e) {ant=p;p=p->prox; }
if (ant==NULL) {/* insere elemento no início */novo->prox=t;t=novo; }else {/* insere elemento no meio */novo->prox=ant->prox;ant->prox=novo; }return t;
}
tplista* insere (tplista *t , tpitem e) {
/* novo nó */tplista *novo;
/* ponteiro p/ anterior */tplista *ant=NULL;
/* ponteiro p/ percorrer */tplista *p=t;
novo = aloca();if (!novo)
return(NULL);novo->info = e;
![Page 34: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/34.jpg)
novo->prox=p; if (ant==NULL)
*t=novo;else
ant->prox=novo; return 1;
}
int insere (tplista **t , tpitem e) {/* Por Referência */tplista *novo;tplista *ant=NULL;tplista *p=*t;novo = aloca();if (!novo)
return 0;novo->info = e;while (p && p->info < e) {
ant=p;
p=p->prox;
}
![Page 35: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/35.jpg)
35
Remoção Procurar o elemento a ser removido e
guardar uma referência para o anterior Se encontrar:
– se for o primeiro: lista passa a apontar para o segundo e espaço do primeiro é liberado
t t
– se estiver no meio ou fim: seu antecessor passa a apontar para seu próximo e o espaço é liberado
![Page 36: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/36.jpg)
if (p==NULL) {
/* Não Achou; retorna NULL */
printf("Não existe\n");
return NULL; }
/* Achou */
if (ant==NULL) {
/* retira elemento do início */
t=p->prox; }
else {
/* retira elemento do meio */
ant->prox=p->prox; }
free(p);
return t;
}
tp_lista* retira (tp_lista *t, tpitem e) {
/* ponteiro p/ anterior */tp_lista *ant=NULL;
/* ponteiro p/ percorrer */tp_lista *p=t;
/* procura elemento na lista,
guardando o anterior */
while (p!=NULL && p->info != e)
{
ant=p;
p=p->prox;
}
![Page 37: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/37.jpg)
int retira (tplista **t, tpitem e) {/* Por Referência */tplista *ant=NULL, *p=*t;while (p!=NULL && p->info!=*e){
ant=p;p=p->prox;
}if (p==NULL)
return 0; else {
if (ant==NULL)*t=p->prox;
else ant->prox=p->prox;
free(p);return 1;
}}
![Page 38: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/38.jpg)
38
Liberar Lista
Liberar todos os elementos alocadosPercorrer todos os elementos,
liberando cada um
É preciso guardar a referência para o próximo antes de liberar o atual
![Page 39: Listas Encadeadassheilacaceres.com/courses/tapfe/ed/5A-listas_encadeadas.pdf · arbitrário da lista, comparando com vetores ... Duplamente encadeada - ponteiros para duas direções](https://reader033.fdocuments.net/reader033/viewer/2022050508/5f990da8e4dd8e481a32bbac/html5/thumbnails/39.jpg)
39
Liberar Lista
void destroi (tplista *t) {tplista *p=t, *q;while (p!=NULL) {
q=p->prox; /* guarda referência p/ o próximo */
free(p); /* libera a memória apontada por p */
p=q; /* faz p apontar para o próximo */
}}