gmlangelohinfufrgsbr material dos profs Anderson Rocha Tavares e Rodrigo Ruas INF01126 Estruturas de Dados I Anteriormente Listas lineares sequências de elementos Listas em contiguidade física ID: 780354
Download The PPT/PDF document "Listas Encadeadas Gabriel Mattos Langelo..." is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1
Listas Encadeadas
Gabriel Mattos Langelohgmlangeloh@inf.ufrgs.br
*material dos profs. Anderson Rocha Tavares e Rodrigo Ruas
INF01126 - Estruturas de Dados I
Slide2Anteriormente...
Listas lineares: sequências de elementos
Listas em contiguidade física:Nós (ou nodos) logicamente adjacentes ficam fisicamente adjacentes na memória
Slide3Análise das operações
Qual a complexidade das operações a seguir para uma lista em contiguidade física?
void
inicializar
(t_lista_cntg *l,
int
cap);
void
destruir(t_lista_cntg *l);int inserir_pos(t_lista_cntg *l, TIPO novo, int pos);int remover(t_lista_cntg *l, int pos);int tamanho(t_lista_cntg* l);TIPO *consultar(t_lista_cntg *l, int pos);int alterar(t_lista_cntg *l, TIPO novo, int pos);
O(n)
O(1)
O(?)*
*Complexidade do malloc indefinida p/ vetores potencialmente grandes
Slide4Análise das operações
Qual a complexidade das operações a seguir para uma lista em contiguidade física?
void
inicializar
(t_lista_cntg *l,
int
cap);
void
destruir(t_lista_cntg *l);int inserir_pos(t_lista_cntg *l, TIPO novo, int pos);int remover(t_lista_cntg *l, int pos);int tamanho(t_lista_cntg* l);TIPO *consultar(t_lista_cntg *l, int pos);int alterar(t_lista_cntg *l, TIPO novo, int pos);
O(n)
O(1)
O(?)*
*Complexidade do malloc indefinida p/ vetores potencialmente grandes
Listas em contiguidade:
Eficientes para consulta (acesso) e alteração
Ineficientes para inserção e remoção
Mesmo inserir_ini e inserir_fim, se houver realocação
Slide5Listas Encadeadas
Slide6Antes de começar...
Como funciona o código abaixo?
https://repl.it/@andertavares/LinkedListConcept
typedef
struct
item { struct item *link;} item;int main() { item *a, *b, *c; a = (item *) malloc(sizeof(item)); a->link = NULL; (...) //continua}a
b
c
Memória
Slide7Antes de começar...
Como funciona o código abaixo?
https://repl.it/@andertavares/LinkedListConcept
typedef
struct
item { struct item *link;} item;int main() { item *a, *b, *c; a = (item *) malloc(sizeof(item)); a->link = NULL; (...) //continua}a
b
c
Memória
link
item
Slide8Antes de começar...
Como funciona o código abaixo?
https://repl.it/@andertavares/LinkedListConcept
typedef
struct
item { struct item *link;} item;int main() { item *a, *b, *c; a = (item *) malloc(sizeof(item)); a->link = NULL; (...) //continua}a
b
c
Memória
link
item
Slide9Antes de começar...
Como funciona o código abaixo?
https://repl.it/@andertavares/LinkedListConcept
typedef
struct
item { struct item *link;} item;int main() { item *a, *b, *c; a = (item *) malloc(sizeof(item)); a->link = NULL; (...) //continua}a
b
c
Memória
link
item
Slide10Antes de começar...
Como funciona o código abaixo?
https://repl.it/@andertavares/LinkedListConcept
typedef
struct
item { struct item *link;} item;int main() { (...)b = (item *) malloc(sizeof(item)); b->link = NULL; a->link = b; (...) //continua}a
b
c
Memória
link
item
link
item
Slide11Antes de começar...
Como funciona o código abaixo?
https://repl.it/@andertavares/LinkedListConcept
typedef
struct
item { struct item *link;} item;int main() { (...)b = (item *) malloc(sizeof(item)); b->link = NULL; a->link = b; (...) //continua}a
b
c
Memória
link
item
link
item
Slide12Antes de começar...
Como funciona o código abaixo?
https://repl.it/@andertavares/LinkedListConcept
typedef
struct
item { struct item *link;} item;int main() { (...)b = (item *) malloc(sizeof(item)); b->link = NULL; a->link = b; (...) //continua}a
b
c
Memória
link
item
link
item
Slide13Antes de começar...
Como funciona o código abaixo?
https://repl.it/@andertavares/LinkedListConcept
typedef
struct
item { struct item *link;} item;int main() { (...)c = (item *) malloc(sizeof(item)); c->link = a; return 0;}a
b
c
Memória
link
item
link
item
link
item
Slide14Antes de começar...
Como funciona o código abaixo?
https://repl.it/@andertavares/LinkedListConcept
typedef
struct
item { struct item *link;} item;int main() { (...)c = (item *) malloc(sizeof(item)); c->link = a; return 0;}a
b
c
Memória
link
item
link
item
link
item
Slide15Prazer, lista encadeada :)
typedef
struct
item
{
struct
item *link;} item;int main() { item *a, *b, *c; a = (item *) malloc(sizeof(item)); a->link = NULL; b = (item *) malloc(sizeof(item)); b->link = NULL; a->link = b;c = (item *) malloc(sizeof(item)); c->link = a;
return 0;}
a
b
c
Memória
link
item
link
item
link
item
Slide16Renomeando os componentes...
typedef
struct
st_nodo
{
struct
st_nodo *link;} t_nodo;abcMemórialinknodo
link
nodo
link
nodo
Slide17Renomeando os componentes...
typedef
struct
st_nodo
{
struct
st_nodo *prox;} t_nodo;abcMemóriaproxprox
prox
Slide18Renomeando os componentes...
typedef
struct
st_nodo
{
TIPO dado;
struct st_nodo *prox;} t_nodo;abcMemória
prox
dado
prox
dado
prox
dado
prox
Slide19Provendo a estrutura lista...
typedef
struct
st_nodo
{
TIPO dado;
struct st_nodo *prox;} t_nodo;typedef struct st_lista_enc { t_nodo *ini;} t_lista_enc;iniMemória
prox
dado
prox
dado
prox
dado
prox
Slide20Relembrando...
TAD: especifica um
conjunto de dados
e
operações
sobre esses dados.
Slide21TAD Lista Encadeada - Estrutura
typedef
struct
st_nodo
{
TIPO dado;
struct st_nodo *prox;} t_nodo;typedef struct st_lista_enc { t_nodo *ini;} t_lista_enc;iniMemória
prox
dado
prox
dado
prox
dado
prox
Componentes:
Nó:
(ou nodo) armazena dados e indica próximo elemento
Ponteiro para o primeiro elemento
(nulo controla o final)
Slide22TAD Lista Encadeada - Operações
Inicialização
Destruição
Tamanho (número de elementos)
Inserção:
inicio, meio, fim ou em ordem
Remoção:
por índice ou por valor
Consulta:
por índice ou por valor
Alteração: por índice ou por valor
Slide23TAD Lista Encadeada
Arquivo .h:
typedef struct
st_nodo
{ ... } t_nodo;
typedef
struct
st_lista_enc { ... } t_lista_enc; void inicializar(t_lista_enc *l);void destruir(t_lista_enc *l);int inserir(t_lista_enc *l, TIPO dado, int pos);int inserir_ord(t_lista_enc *l, TIPO dado);int remover(t_lista_enc *l, int pos);TIPO *consultar(t_lista_enc *l, int pos);
int
buscar(t_lista_enc *l, TIPO dado);int
alterar(t_lista_enc *l, TIPO novo, int
pos);int tamanho
(t_lista_enc *l);
Slide24Listas Encadeadas - Conceito
Lista com uma estrutura unitária que referencia o próximo elemento. O número de elementos cresce e diminui dinamicamente.
Não necessita reajuste de capacidadeEstrutura dinâmica!
Não preciso saber a quantidade de elementos a princípio
Slide25Listas Encadeadas: atenção
Elementos não estão em posições contíguas na memória.
Isso acarreta alguns compromissos:A alocação e liberação de novos elementos ocorre dinamicamente. O programador precisa controlar isso com
malloc
e
free
O operador de acesso a vetores
[
] não funciona, pois é específico para memória contígua (ou seja, nada de lista[indice])Se perder o ponteiro para um elemento, não poderá mais recuperá-lo. Se esse elemento possui sucessores na lista, eles também serão perdidos.
Slide26Sintaxe:
void inicializar
(t_lista_enc *l);/* Inicializa a lista encadeada apontada por *l.
Parâmetros: ponteiro para a estrutura lista encadeada
Retorno: sem retorno */
Listas Encadeadas: inicialização
(uso)
t_lista_enc minha_lista;inicializar(&minha_lista);
Slide27Procedimentos necessários:
1. Estabelece as condições iniciais necessárias
Listas Encadeadas: criação (implementação)
void
inicializar
(t_lista_enc *l) {
l->ini =
NULL
;
}ini
Slide28Sintaxe:
int inserir
(t_lista_enc *l, TIPO dado, int pos);
/* Insere um elemento na lista na posição determinada
Parâmetros: ponteiro para a lista encadeada
,
elemento a ser inserido e posicao (1a posição é zero)
.
Retorno: 1 em caso de sucesso, e 0 em caso de falha */
Listas Encadeadas: inserção (uso)t_lista_enc minha_lista;int numero;(...) // inicializa a lista e o numeroinserir(&minha_lista, numero, 3); //insere na 4a pos.
Slide29Procedimentos necessários:
1. Aloca espaço na memória para armazenar elemento2. Procura pela posição correta do elemento
3. Manipula ponteiros para trocar ordem dos elementos
inserir(lista, 15, 2); //inserir elemento 15 na 3ª posição
Listas Encadeadas: inserção
(implementação)
ini3prox75prox-1
prox
Slide30Procedimentos necessários:
1. Aloca espaço na memória para armazenar elemento2. Procura pela posição correta do elemento
3. Manipula ponteiros para trocar ordem dos elementos
inserir(lista, 15, 2); //inserir elemento 15 na 3ª posição
Listas Encadeadas: inserção
(implementação)
15
proxinilista:
Slide31Listas Encadeadas: inserção (implementação)
15
prox
ini
lista:
3
prox
posicao
: 0
atual = lista->ini
atualProcedimentos necessários:
1. Aloca espaço na memória para armazenar elemento2. Procura pela posição correta do elemento
3. Manipula ponteiros para trocar ordem dos elementosinserir(lista, 15, 2); //inserir elemento 15 na 3ª posição
Listas Encadeadas: inserção (implementação)
15
prox
ini
lista:
3
prox
posicao: 1
atual = atual->prox
atual
75
prox
Procedimentos necessários:
1.
Aloca espaço na memória para armazenar elemento2. Procura pela posição correta do elemento3. Manipula ponteiros para trocar ordem dos elementos
inserir(lista, 15, 2); //inserir elemento 15 na 3ª posição
Listas Encadeadas: inserção (implementação)
15
prox
ini
lista:
3
prox
posicao: 2
atual = atual->prox
atual
75
prox
-1
prox
Procedimentos necessários:
1.
Aloca espaço na memória para armazenar elemento
2. Procura pela posição correta do elemento
3.
Manipula ponteiros para trocar ordem dos elementos
inserir(lista, 15, 2); //inserir elemento 15 na 3ª posição
Procedimentos necessários:
1. Aloca espaço na memória para armazenar elemento2. Procura pela posição correta do elemento
3. Manipula ponteiros para trocar ordem dos elementos
inserir(lista, 15, 2); //inserir elemento 15 na 3ª posição
Listas Encadeadas: inserção
(implementação)
15
proxinilista:3prox
posicao: 0anterior = NULL
atual = lista->ini
atual
ant
Slide35Procedimentos necessários:
1. Aloca espaço na memória para armazenar elemento2. Procura pela posição correta do elemento
3. Manipula ponteiros para trocar ordem dos elementos
inserir(lista, 15, 2); //inserir elemento 15 na 3ª posição
Listas Encadeadas: inserção
(implementação)
15
proxinilista:3prox
posicao: 1anterior = atual
atual = atual->prox
atual
75
prox
ant
Slide36Procedimentos necessários:
1. Aloca espaço na memória para armazenar elemento2. Procura pela posição correta do elemento
3. Manipula ponteiros para trocar ordem dos elementos
inserir(lista, 15, 2); //inserir elemento 15 na 3ª posição
Listas Encadeadas: inserção
(implementação)
15
proxinilista:3prox
posicao: 2anterior = atual
atual = atual->prox
atual
75
prox
-1
prox
ant
Slide37Procedimentos necessários:
1. Aloca espaço na memória para armazenar elemento2. Procura pela posição correta do elemento
3. Manipula ponteiros p/ trocar ordem dos elementos
inserir(lista, 15, 2); //inserir elemento 15 na 3ª posição
Listas Encadeadas: inserção
(implementação)
15
proxinilista:3proxanterior->prox = novo
atual
75
prox
-1
prox
ant
novo->prox = atual
Slide38Procedimentos necessários:
1. Aloca espaço na memória para armazenar elemento
2. Procura pela posição correta do elemento3. Manipula ponteiros para trocar ordem dos elementos
int
inserir
(t_lista_enc *l, TIPO dado,
int
pos){ int i = 0; t_nodo *novo = NULL; // Ponteiro para novo elemento t_nodo *ant = NULL; // Aux. para a posição anterior t_nodo *atual = l->ini; // Aux. para percorrer a lista novo = (t_nodo*)malloc(sizeof(t_nodo)); // Aloca novo nodo if (novo == NULL) { return 0; // Falta de memoria! } novo->dado = dado; ...}
Listas Encadeadas: inserção (implementação)
Slide39Procedimentos necessários:
1. Aloca espaço na memória para armazenar elemento
2. Procura pela posição correta do elemento3. Manipula ponteiros para trocar ordem dos elementos
Listas Encadeadas: inserção
(implementação)
int
inserir
(t_lista_enc *l, TIPO dado, int pos){ ... // Procura a posição de inserção while((atual != NULL) && i<pos) { ant = atual; atual = atual->prox; i++; } ...}
Slide40Procedimentos necessários:
1. Aloca espaço na memória para armazenar elemento
2. Procura pela posição correta do elemento3. Manipula ponteiros p/ trocar ordem dos elementos
Listas Encadeadas: inserção
(implementação)
int
inserir
(t_lista_enc *l, TIPO dado, int pos){ ... //Encadeia o elemento if (ant == NULL) { //Insere na 1a pos. (também p/ lista vazia) novo->prox = l->ini; l->ini = novo; } else { // Insere no meio (ou final) da lista novo->prox = atual; ant->prox = novo; } return 1; // Sucesso!}
Slide41Código completo:
int
inserir
(t_lista_enc *l, TIPO dado,
int
pos){
int
i=0;
t_nodo *novo = NULL; // Ponteiro para novo elemento t_nodo *ant = NULL; // Aux. para a posição anterior t_nodo *atual = l->ini; // Aux. para percorrer a lista novo = (t_nodo *)malloc(sizeof(t_nodo )); // Aloca um novo nodo if (novo == NULL) { return 0; // Falta de memoria! } novo->dado = dado; // Procura a posição de inserção while((atual != NULL) && i<pos) { ant = atual; atual = atual->prox; i++;
}// Encadeia o elemento if
(ant == NULL) { //Insere na 1a pos. (também
p/ lista vazia) novo->prox = l->ini; l->ini = novo;
} else { // Insere no meio (ou final) da lista
novo->prox = atual; ant->prox = novo; }
return 1; // Sucesso!
}
Listas Encadeadas: inserção
(implementação)
Slide42Sintaxe:
int inserir_ord
(t_lista_enc *l, TIPO dado);/* Insere um elemento na lista de forma ordenada
Parâmetros: ponteiro para a estrutura lista encadeada, e
elemento a ser inserido.
Retorno: 1 em sucesso, 0 em falha */
Listas Encadeadas: inserção ordenada (uso)t_lista_enc minha_lista;int numero;(...) // inicializa a listainserir_ord(&minha_lista, numero);
Slide43Procedimentos necessários:
1. Aloca espaço na memória para armazenar elemento2. Procura pela posição correta do elemento
3. Manipula ponteiros para trocar ordem dos elementos
inserir_ord(lista, 15); //inserir o elemento 15 em ordem
Listas Encadeadas: inserção ord.
(impl.)
ini
3
prox5prox21
prox
Slide44ini
lista:
Procedimentos necessários:
1.
Aloca espaço na memória para armazenar elemento
2.
Procura pela posição correta do elemento
3.
Manipula ponteiros para trocar ordem dos elementos
inserir_ord(lista, 15); //inserir o elemento 15 em ordem15proxListas Encadeadas: inserção ord. (impl.)
Slide45ini
lista:
Procedimentos necessários:
1.
Aloca espaço na memória para armazenar elemento
2.
Procura pela posição correta do elemento
3.
Manipula ponteiros para trocar ordem dos elementos
inserir_ord(lista, 15); //inserir o elemento 15 em ordemini3proxatualant
15
prox
Listas Encadeadas: inserção ord.
(impl.)
Slide46ini
lista:
Procedimentos necessários:
1.
Aloca espaço na memória para armazenar elemento
2.
Procura pela posição correta do elemento
3.
Manipula ponteiros para trocar ordem dos elementos
inserir_ord(lista, 15); //inserir o elemento 15 em ordemini3proxatualant
5
prox
15
prox
Listas Encadeadas: inserção ord.
(impl.)
Slide47ini
lista:
Procedimentos necessários:
1.
Aloca espaço na memória para armazenar elemento
2.
Procura pela posição correta do elemento
3.
Manipula ponteiros para trocar ordem dos elementos
inserir_ord(lista, 15); //inserir o elemento 15 em ordemini3prox5prox
atual
ant
21
prox
15
prox
Listas Encadeadas: inserção ord.
(impl.)
Slide48Procedimentos necessários:
1. Aloca espaço na memória para armazenar elemento2. Procura pela posição correta do elemento
3. Manipula ponteiros p/ trocar ordem dos elementos
inserir_ord(lista, 15); //inserir o elemento 15 em ordem
15
prox
ini
lista:
ini3prox
5
prox
atual
ant
21
prox
Listas Encadeadas: inserção ord.
(impl.)
Slide49Procedimentos necessários:
1. Aloca espaço na memória para armazenar elemento
2. Procura pela posição correta do elemento3. Manipula ponteiros para trocar ordem dos elementos
int
inserir_ord
(t_lista_enc *l, TIPO dado){
...
// Procura a posição de inserção while((atual != NULL) && (atual->dado < novo->dado)) { ant = atual; atual = atual->prox; } ...}Listas Encadeadas: inserção ord. (impl.)
Slide50Código completo:
void
inserir_ord
(t_lista_enc *l, TIPO dado){
t_nodo *novo =
NULL
;
// Ponteiro para novo elemento
t_nodo *ant =
NULL; // Aux. para a posição anterior t_nodo *atual = l->ini; // Aux. para percorrer a lista novo = (t_nodo *)malloc(sizeof(t_nodo )); // Aloca um novo nodo if (novo == NULL) { return 0; // Falta de memoria! } novo->dado = dado; // Procura a posição de inserção while((atual != NULL) && (atual->dado < novo->dado)) { ant = atual; atual = atual->prox; } // Encadeia o elemento
if (ant == NULL) { //Insere na 1a posição (também p/ lista vazia)
novo->prox = l->ini; l->ini = novo;
} else { // Insere no meio (ou final) da lista
novo->prox = ant->prox; ant->prox = novo; }
return 1 // Sucesso!}
Listas Encadeadas: inserção ord.
(impl.)
Slide51Sintaxe:
int remover
(t_lista_enc *l, int pos);
/* Remove da lista um elemento de uma posição definida
Parâmetros: ponteiro para a estrutura lista encadeada
e posição.
Retorno: 1 em caso de sucesso, e 0 em caso de falha */
Listas Encadeadas: remoção (uso)t_lista_enc minha_lista;(...) // inicializa a lista e insere elementosif (remover(&minha_lista, 9)) printf("Removido com sucesso\n");else printf("Erro!\n");
Slide52Procedimentos necessários:
1. Procura elemento a ser removido2. Manipula ponteiros
3. Libera memória, apagando elemento
remover
(lista, 1); //remover da posicao 1 (segundo elemento)
Listas Encadeadas: remoção
(implementação)ini3prox5prox21
prox
Slide53Procedimentos necessários:
1. Procura elemento a ser removido2. Manipula ponteiros
3. Libera memória, apagando elemento
remover(lista, 1); //remover da posicao 1 (segundo elemento)
Listas Encadeadas: remoção
(implementação)
ini
3proxinilista:ini
3
prox
atual
ant
Slide54Procedimentos necessários:
1. Procura elemento a ser removido2. Manipula ponteiros
3. Libera memória, apagando elemento
remover(lista, 1); //remover da posicao 1 (segundo elemento)
Listas Encadeadas: remoção
(implementação)
ini
3proxinilista:ini
3
prox
atual
ant
5
prox
Slide55Procedimentos necessários:
1. Procura elemento a ser removido2. Manipula ponteiros
3. Libera memória, apagando elemento
remover(lista, 1); //remover da posicao 1 (segundo elemento)
Listas Encadeadas: remoção
(implementação)
ini
3proxinilista:ini3
prox
atual
ant
5
prox
21
prox
Slide56Procedimentos necessários:
1. Procura elemento a ser removido2. Manipula ponteiros
3. Libera memória, apagando elemento
remover(lista, 1); //remover da posicao 1 (segundo elemento)
Listas Encadeadas: remoção
(implementação)
ini
3proxinilista:ini3
prox
atual
ant
5
prox
21
prox
free
Slide57Procedimentos necessários:
1. Procura elemento a ser removido2. Manipula ponteiros
3. Desaloca memória para o elemento a ser removido
int
remover
(t_lista_enc *l,
int
pos) {
int i = 0; t_nodo *ant = NULL; // Aux. para anterior t_nodo *atual = l->ini; // Aux. p/ percorrer a lista // Procura o elemento na lista while(atual != NULL && i < pos) { ant = atual; atual = atual->prox; i++; } ... }Listas Encadeadas: remoção (implementação)
Slide58Procedimentos necessários:
1. Procura elemento a ser removido2. Manipula ponteiros
3. Desaloca memória para o elemento a ser removido
Listas Encadeadas: remoção
(implementação)
int
remover
(t_lista_enc *l,
int
pos) { ... if(atual == NULL) return 0; //nao achou if(ant == NULL) { // Vai remover o primeiro elemento l->ini = atual->prox; // ou l->ini = null; } else { // Vai remover do meio ou do final ant->prox = atual->prox; } ...}
Slide59Procedimentos necessários:
1. Procura elemento a ser removido2. Manipula ponteiros
3. Desaloca memória para o elemento a ser removido
Listas Encadeadas: remoção
(implementação)
int
remover
(t_lista_enc *l,
int
pos) { ... free(atual); // Libera a memória alocada return 1;}
Slide60Código completo:
int
remover
(t_lista_enc *l,
int
pos) {
int
i = 0;
t_nodo *ant = NULL; // Aux. para a posição anterior t_nodo *atual = l->ini; // Aux. para percorrer a lista // Procura o elemento na lista while(atual != NULL && i < pos) { ant = atual; atual = atual->prox; i++; } if(atual == NULL) return 0; //nao achou if(ant == NULL) { // Vai remover o primeiro elemento l->ini = atual->prox; } else { // Vai remover do meio ou do final
ant->prox = atual->prox; }
free(atual); // Libera a memória alocada
return 1;}
Listas Encadeadas: remoção (implementação)
Slide61Sintaxe:
void destruir
(t_lista_enc *l);/* Destrói uma lista previamente criada e libera a memória usada
Parâmetros: ponteiro para a estrutura lista encadeada
Retorno: sem retorno */
Listas Encadeadas: destruição
(uso)
lista_cntg_t minha_lista;int n_elem;scanf("%d", &n_elem);inicializa(&minha_lista, n_elem);(...) // usa a lista de diversas formasdestruir(&minha_lista);
Slide62Procedimentos necessários:
Remove todos os elementos, liberando memória
Listas Encadeadas: destruição
(implementação)
ini
3
prox
ini
lista:
ini3prox
atual
5
prox
21
prox
Slide63Procedimentos necessários:
Remove todos os elementos, liberando memória
Listas Encadeadas: destruição
(implementação)
ini
3
prox
ini
lista:
ini3proxatual
5
prox
21
prox
Slide64Procedimentos necessários:
Remove todos os elementos, liberando memória
Listas Encadeadas: destruição
(implementação)
ini
ini
lista:
ini
atual
5prox21
prox
Slide65Procedimentos necessários:
Remove todos os elementos, liberando memória
Listas Encadeadas: destruição
(implementação)
ini
ini
lista:
ini
atual
5prox21
prox
Slide66Procedimentos necessários:
Remove todos os elementos, liberando memória
Listas Encadeadas: destruição
(implementação)
ini
ini
lista:
ini
atual
21prox
Slide67Procedimentos necessários:
Remove todos os elementos, liberando memória
Listas Encadeadas: destruição
(implementação)
ini
ini
lista:
ini
atual
21prox
Slide68Procedimentos necessários:
Remove todos os elementos, liberando memória
Listas Encadeadas: destruição
(implementação)
ini
ini
lista:
ini
atual
Slide69Procedimentos necessários:
Remove todos os elementos, liberando memória
void
destruir
(t_lista_enc *l) {
t_nodo *atual;
while
(l->ini != NULL) { atual = l->ini; l->ini = l->ini->prox; free(atual); }}void destruir(t_lista_enc *l) { while( remover(l, 0) );}Listas Encadeadas: destruição (implementação)
Slide70Sintaxe:
TIPO *consulta(t_lista_enc *l,
int pos);
/* Retorna um elemento na posição desejada
Parâmetros: ponteiro para a estrutura lista encadeada
e posição (int pos).
Retorno: ponteiro para elemento em caso de sucesso, e NULL em caso de falha */
Listas Encadeadas: consulta (uso)t_lista_enc minha_lista;int indice;(...) // inicializa e usa a listaint *dado = consulta(&minha_lista, indice)if (dado != NULL) printf("O valor na posicao %d e' %s\n", indice, *dado);else printf("O elemento nao existe!\n");
Slide71Procedimentos necessários:
1. Procura pelo elemento na lista, na posição desejada2. Retorna o ponteiro apropriadamente
Listas Encadeadas: consulta
(implementação)
TIPO *
consulta
(t_lista_enc *l,
int
pos) {
int i = 0; t_nodo *atual = l-> ini; // Aux. para percorrer a lista while (atual != NULL && i<pos) { atual = atual->prox; i++; } if (atual != NULL) return &atual->dado; else return NULL;}
Slide72Sintaxe:
int buscar
(t_lista_enc *l, TIPO dado);/* Retorna o índice onde o valor estiver, ou -1 se não for encontrado
Parâmetros: ponteiro para a estrutura lista encadeada e o valor
Retorno:
índice onde o valor estiver, ou -1 se não for encontrado
*/
Listas Encadeadas: busca
(uso)t_lista_enc minha_lista;int valor;(...) // inicializa e usa a listaint *dado = consulta_val(&minha_lista, valor)if (dado != NULL) printf("O elemento existe.\n");else printf("O elemento nao existe!\n");
Slide73Procedimentos necessários:
1. Procura pelo elemento na lista, com o valor desejado2. Retorna um ponteiro para o elemento na posição desejada
int
buscar
(t_lista_enc *l, TIPO dado){
t_nodo *atual = l->ini;
// Aux. para percorrer a lista
int pos = 0; while (atual != NULL && atual->dado != dado) { pos++; atual = atual->prox; } if (atual != NULL) return pos; else return -1;}Listas Encadeadas: consulta (implementação)
Slide74Procedimentos necessários:
1. Procura pelo elemento na lista, com o valor desejado2. Retorna um ponteiro para o elemento na posição desejada
int
buscar
(t_lista_enc *l, TIPO dado){
t_nodo *atual = l->ini;
// Aux. para percorrer a lista
int pos = 0; while (atual != NULL && atual->dado != dado) { pos++; atual = atual->prox; } if (atual != NULL) return pos; else return -1;}Atenção: é possível fazer uma busca por um campo do tipo. Exemplo:
struct
st_livro
{
int
ano;
char
titulo[200];
...
};
int
buscar_por_ano
(t_lista_enc *l, int ano){
t_nodo *atual = l->ini;
int
pos = 0;
while
(atual !=
NULL
&&
atual->dado.ano != ano
) {
pos++;
atual = atual->prox;
}
if
(atual !=
NULL
)
return
pos;
else
return
-1;
}
Listas Encadeadas: consulta
(implementação)
Slide75Sintaxe:
int alterar
(t_lista_enc *l, TIPO novo, int pos);
/* Substitui o elemento da posição desejada
Parâmetros: ponteiro para a estrutura lista encadeada,
elemento com novos valores e posição .
Retorno: 1 em caso de sucesso, e 0 em caso de falha */
Listas Encadeadas: alteração (uso)t_lista_enc minha_lista;int elem;(...) // inicializa a lista e o item if (alterar(&minha_lista, elem, 3)) printf("Dado substituido com sucesso\n");else printf("Erro!\n");
Slide76Procedimentos necessários:
1. Tenta encontrar o elemento a ser alterado2. Se não encontrou, retorna falso; senão substitui e retorna verdadeiro
Listas Encadeadas: alteração
(implementação)
int
alterar
(t_lista_enc *l, TIPO novo,
int
pos) { TIPO *atual = consulta(l, pos); if (atual == NULL) return 0; // Posição inválida *atual = novo; return 1;}
Slide77Sintaxe:
int tamanho
(t_lista_enc *l);/* Fornece o tamanho (nro de elementos) da lista
Parâmetros: estrutura lista encadeada
Retorno: número de elementos armazenados na lista */
Listas Encadeadas: tamanho
(uso)
t_lista_enc minha_lista;int n_elem;(...) // inicializa a listaif (tamanho(&minha_lista) == 0) printf("lista vazia\n");else printf("existem %d elementos na lista\n", tamanho(&minha_lista));
Slide78Procedimentos necessários:
1. Conta o número de elementos
Listas Encadeadas: tamanho (implementação)
int
tamanho
(t_lista_enc *l){
int
cont = 0;
t_nodo *atual = l->ini; while (atual != NULL) { cont++; atual = atual->prox; } return cont;}
Slide79Perguntas
Como otimizar a função tamanho?Como implementar uma função para inserir sempre no início da lista?
E no fim?Como implementar uma função para sempre remover o primeiro elemento da lista?
E o último?
Slide80Perguntas
Como otimizar a função tamanho?
typedef
struct
st_lista_enc
{ t_nodo *ini; int tamanho;} t_lista_enc;/* inicializa o tamanho em 0 e atualiza conforme necessario */
Slide81Perguntas
Como implementar uma função para inserir sempre no início da lista?
E no fim?
int
prepend
(t_lista_enc *l, TIPO dado){
inserir(l, dado, 0);
}
int
append(t_lista_enc *l, TIPO dado){ inserir(l, dado, tamanho(l));}Qual a complexidade?Dá pra fazer melhor?
Slide82Perguntas
Como implementar uma função para sempre remover o primeiro elemento da lista?
E o último?
int
remover_ini
(t_lista_enc *l){
remover(l, 0);
}
int
remover_fim(t_lista_enc *l){ remover(l, tamanho(l) - 1);}Qual a complexidade?Dá pra fazer melhor?
Slide83Qual a complexidade de cada função?
void
inicializar(t_lista_enc *l
);
void
destruir
(t_lista_enc *l);
int
inserir(t_lista_enc *l, TIPO dado, int pos);int prepend(t_lista_enc *l, TIPO dado);int append(t_lista_enc *l, TIPO dado);int inserir_ord(t_lista_enc *l, TIPO dado);int remover(t_lista_enc *l, int pos);TIPO *consultar(t_lista_enc *l, int pos);int
buscar(t_lista_enc *l, TIPO dado);int
alterar(t_lista_enc *l, TIPO novo, int
pos);int tamanho
(t_lista_enc *l);
Slide84Listas Encadeadas - Características
Eficientes para inserção nas pontas
Ineficientes para inserção em posição arbitrária
Eficientes para remoção no início
Ineficientes para remoção em posição arbitrária
Ineficientes para acesso
Não requer realocação de espaço
Tem sempre a “medida certa”