07/04/2015 1
Estrutura de Dados para
Tecnologia
10/10/08 2
Listas Encadeadas
É uma representação de uma sequência de objetos
armazenados na memória do computador.
Cada objeto ou elemento da sequência é armazenado
em uma célula da lista: o primeiro elemento na primeira célula, o segundo elemento na segunda célula e assim por diante.
Difere de VETOR pois:
Não é necessário pré-definir o tamanho da lista.
Os elementos não estão necessariamente alocados em
espaços contíguos na memória.
10/10/08 3
Listas Encadeadas
Podem ser:
Simplesmente Encadeadas (lineares)
cada célula conterá um objeto de algum tipo e o endereço da célula
seguinte.
A última célula não apontará para nenhum endereço de célula seguinte
Duplamente Encadeadas (lineares)
Cada célula conterá além de um objeto de algum tipo, o endereço da
célula anterior e o endereço da célula seguinte.
A primeira célula não apontará para nenhum endereço de célula
anterior
A última célula não apontará para nenhum endereço de célula seguinte
Circulares
Cada célula conterá além de um objeto de algum tipo e o endereço da
célula seguinte (pode conter também o endereço da célula anterior).
A última célula apontará para a primeira célula, como célula seguinte
10/10/08 4
Listas Encadeadas
Representação de um nó em uma lista simplesmente
encadeada:
Representação de uma lista simplesmente
encadeada:
objeto
objeto
objeto objeto objeto
Listas Encadeadas
Definindo lista simplesmente encadeada (exemplo):
typedef struct strnode {
int valor;
struct strnode* proximo; } node;
typedef node* lista; lista l;
3 6 7 9
10/10/08 6
Listas Encadeadas
Operações em listas simplesmente encadeadas:
Criar lista;
Consultar/Mostrar lista;
Inserir um novo elemento no início da lista;
Inserir um novo elemento no final da lista;
Inserir um novo elemento em qualquer posição da lista;
Remover um elemento do início da lista;
Remover um elemento do final da lista;
Criando a lista:
void cria_lista(lista *l) {
*l = NULL; } ... int main() { lista l; ... cria_lista(&l); ... }
10/10/08 7
Listas Encadeadas
Inserindo um novo elemento no início da lista:
10/10/08 8
Listas Encadeadas
l
7
Inserindo um novo elemento no início da lista:
Listas Encadeadas
l
7 3
Inserindo um novo elemento no início da lista:
10/10/08 10
Listas Encadeadas
l
7 3
4
Inserindo um novo elemento no início da lista:
Listas Encadeadas
l
7 3
4 1
Inserindo um novo elemento no início da lista:
10/10/08 12
Listas Encadeadas
l
7 3
Inserindo um novo elemento no início da lista:
void insere_inicio(lista *l, int valor) {
node* no = (node *) malloc(sizeof(node)); no->valor = valor;
if(*l == NULL) // A lista está vazia ? no->proximo = NULL;
else
no->proximo = *l; *l = no;
printf("Elemento inserido com sucesso !\n"); }
Inserindo um novo elemento no final da lista:
10/10/08 14
Listas Encadeadas
l
7
Inserindo um novo elemento no final da lista:
Listas Encadeadas
l
7 3
aux
Inserindo um novo elemento no final da lista:
10/10/08 16
Listas Encadeadas
l
7 3
aux
4
Inserindo um novo elemento no final da lista:
Listas Encadeadas
l
7 3
aux
4
Inserindo um novo elemento no final da lista:
10/10/08 18
Listas Encadeadas
l
7 3
aux
4 1
Inserindo um novo elemento no final da lista:
Listas Encadeadas
l
7 3
aux
4 1
Inserindo um novo elemento no final da lista:
10/10/08 20
Listas Encadeadas
l
7 3
aux
4 1
Inserindo um novo elemento no final da lista:
void insere_fim(lista *l, int valor) {
lista aux;
node* no = (node *) malloc(sizeof(node)); no->valor = valor;
no->proximo = NULL;
if(*l == NULL) // A lista está vazia ? *l = no;
else {
aux = *l;
while(aux->proximo != NULL) // caminha até o final da lista aux = aux->proximo;
aux->proximo = no; }
printf("Elemento inserido com sucesso !\n"); }
Mostrando a lista:
void mostra_lista(lista l) {
if(l == NULL) // A lista está vazia ? printf("A lista está vazia !\n");
else {
printf("Elementos da lista: "); while(l != NULL)
{
printf("%5d --> ",l->valor); l = l->proximo;
} } }
10/10/08 22
Listas Encadeadas: Exercícios
Elabore um procedimento que dado um valor inteiro
qualquer, insira um novo nó em uma lista
simplesmente encadeada com este valor caso o mesmo ainda não exista na lista, em ordem
CRESCENTE, ou seja, sempre entre um nó contendo um valor menor e outro contendo um valor maior que o valor a ser inserido.
Elabore um procedimento que dado um valor inteiro
10/10/08 24
Listas Encadeadas
O encadeamento simples permite percorrer a lista
somente em um único sentido.
A partir de um elemento qualquer da lista, não é possível acessar o elemento anterior ao mesmo.
E se quisermos acessar o elemento anterior a outro
elemento ?
E se quisermos percorrer a lista no sentido inverso ?
Para isso, podemo usar listas lineares DUPLAMENTE
Listas Encadeadas
Representação de um nó em uma lista duplamente
encadeada:
Representação de uma lista duplamente encadeada
(com sentinela): (Cabeça da) Lista
objeto
Definindo lista duplamente encadeada (exemplo):
typedef struct strnode {
int valor;
struct strnode* anterior; struct strnode* proximo; } node;
typedef struct strlista {
node* inicio; node* fim; } lista;
lista l;
10/10/08 26
Listas Encadeadas
Operações em listas duplamente encadeadas:
Criar lista;
Consultar/Mostrar lista em ordem normal;
Consultar/Mostrar lista em ordem inversa;
Inserir um novo elemento no início da lista;
Inserir um novo elemento no final da lista;
Inserir um novo elemento em qualquer posição da lista;
Remover um elemento do início da lista;
Remover um elemento do final da lista;
Criando a lista:
void cria_lista(lista *l) {
l->inicio = NULL; l->fim = NULL; } ... int main() { lista l; ... cria_lista(&l); ... }
10/10/08 28
Listas Encadeadas
início
l
Inserindo um novo elemento no início da lista:
Listas Encadeadas
l
Inserindo um novo elemento no início da lista:
10/10/08 30
Listas Encadeadas
l
Inserindo um novo elemento no início da lista:
Listas Encadeadas
l
7 3
Inserindo um novo elemento no início da lista:
10/10/08 32
Listas Encadeadas
l
7 3
1
Inserindo um novo elemento no início da lista:
Listas Encadeadas
l
7 3
Inserindo um novo elemento no início da lista:
void insere_inicio(lista *l, int valor) {
node* no = (node *) malloc(sizeof(node)); no->valor = valor;
no->anterior = NULL;
if(l->inicio == NULL) // A lista está vazia ? {
no->proximo = NULL; l->fim = no;
} else {
l->inicio->anterior = no; no->proximo = l->inicio; }
l->inicio = no;
printf("Elemento inserido com sucesso !\n"); }
10/10/08 34
Inserindo um novo elemento no final da lista:
Listas Encadeadas
l
Inserindo um novo elemento no final da lista:
10/10/08 36
Listas Encadeadas
l
7
Inserindo um novo elemento no final da lista:
Listas Encadeadas
l
7 4
Inserindo um novo elemento no final da lista:
10/10/08 38
Listas Encadeadas
l
7 4
1
Inserindo um novo elemento no final da lista:
Listas Encadeadas
l
Inserindo um novo elemento no final da lista:
void insere_fim(lista *l, int valor) {
node* no = (node *) malloc(sizeof(node)); no->valor = valor;
no->proximo = NULL;
if(l->inicio == NULL) // A lista está vazia {
no->anterior = NULL; l->inicio = no;
} else {
l->fim->proximo = no; no->anterior = l->fim; }
l->fim = no;
printf("Elemento inserido com sucesso !\n"); }
10/10/08 40
Mostrando a lista em ordem normal:
void mostra_ordem(lista l) {
node* no = l.inicio;
if(no == NULL) // A lista está vazia ? printf("A lista está vazia !\n");
else {
printf("Elementos da lista: "); while(no != NULL)
{
printf("%5d --> ",no->valor);
no = no->proximo;
} } }
10/10/08 41
Mostrando a lista em ordem inversa:
void mostra_inversa(lista l) {
node* no = l.fim;
if(no == NULL) // A lista está vazia ? printf("A lista está vazia !\n");
else {
printf("Elementos da lista: "); while(no != NULL)
{
printf("%5d --> ",no->valor); no = no->anterior;
} } }
10/10/08 42
Listas Encadeadas: Exercícios
Elabore um procedimento que dado um valor inteiro
qualquer, insira um novo nó em uma lista
duplamente encadeada com este valor caso o mesmo ainda não exista na lista, em ordem CRESCENTE, ou seja, sempre entre um nó contendo um valor menor e outro contendo um valor maior que o valor a ser inserido.
Elabore um procedimento que dado um valor inteiro
10/10/08 44
Listas Encadeadas
Listas Circulares:
Podem ser simplesmente encadeadas ou duplamente
encadeadas.
Em listas circulares simplesmente encadeadas, a última
célula apontará para a primeira célula, como célula seguinte.
Em listas circulares duplamente encadeadas, ainda será
necessário que a primeira célula aponte para a última, como célula anterior.
Não é mais aplicável a idéia de “início” e “fim” da lista (o
caminhamento poderá ser infinito).
Armazena-se, pelo menos, o endereço de um “cabeça de
lista” para que se possa iniciar o caminhamento (e também
Listas Encadeadas
Representação de uma uma lista circular
simplesmente encadeada:
objeto objeto objeto objeto
Definindo lista circular simplesmente encadeada (exemplo):
typedef struct strnode {
int valor;
struct *strnode; } node;
typedef node* lista; lista l;
10/10/08 46
Listas Encadeadas
3 6 7 9
Inserindo um novo elemento no final da lista: void insere_fim(lista *l, int valor)
{
lista aux;
node* no = (node *) malloc(sizeof(node)); no->valor = valor;
if(*l == NULL) // A lista está vazia ? {
no->proximo = no; *l = no;
}
else // A lista já possui pelo menos um elemento {
aux = *l;
while(aux->proximo != *l) aux = aux->proximo; no->proximo = aux->proximo; aux->proximo = no;
}
printf("Elemento inserido com sucesso !\n");
10/10/08 47
10/10/08 48
Listas Encadeadas: Exercícios
Elabore um procedimento que dado um valor inteiro
qualquer, insira um novo nó no início de uma lista circular simplesmente encadeada com este valor.
Elabore um procedimento que dado um valor inteiro
Listas Encadeadas
Representação de uma uma lista circular duplamente
encadeada:
(Cabeça da) Lista
Definindo lista circular duplamente encadeada (exemplo):
typedef struct strnode {
int valor;
struct strnode* anterior; struct strnode* proximo; } node;
typedef *node lista lista l;
10/10/08 50
Listas Encadeadas
3 4 1
7
Inserindo um novo elemento no início da lista:
void insere_inicio(lista *l, int valor) {
node* no = (node *) malloc(sizeof(node)); no->valor = valor;
if(*l == NULL) // A lista está vazia ? {
no->anterior = no; no->proximo = no; }
else {
(*l)->anterior->proximo = no; no->anterior = (*l)->anterior; (*l)->anterior = no;
no->proximo = *l; }
*l = no;
printf("Elemento inserido com sucesso !\n");
Inserindo um novo elemento no início da lista:
10/10/08 52
Listas Encadeadas
l
Inserindo um novo elemento no início da lista:
Listas Encadeadas
l
7
Inserindo um novo elemento no início da lista:
10/10/08 54
Listas Encadeadas
l
7
Inserindo um novo elemento no início da lista:
Listas Encadeadas
l
7
Inserindo um novo elemento no início da lista:
10/10/08 56
Listas Encadeadas
l
7
Inserindo um novo elemento no início da lista:
Listas Encadeadas
l
7
Inserindo um novo elemento no início da lista:
10/10/08 58
Listas Encadeadas
l
7
Inserindo um novo elemento no início da lista:
Listas Encadeadas
l
7
3 4
Inserindo um novo elemento no início da lista:
10/10/08 60
Listas Encadeadas
l
7
3 4
Inserindo um novo elemento no início da lista:
Listas Encadeadas
l
7
3 4
Inserindo um novo elemento no início da lista:
10/10/08 62
Listas Encadeadas
l
7
3 4
Inserindo um novo elemento no final da lista:
void insere_fim(lista *l, int valor) {
node* no = (node *) malloc(sizeof(node)); no->valor = valor;
if(*l == NULL) // A lista está vazia {
no->anterior = no; no->proximo = no; *l = no;
} else {
(*l)->anterior->proximo = no; no->anterior = (*l)->anterior; (*l)->anterior = no;
no->proximo = *l; }
printf("Elemento inserido com sucesso !\n");
10/10/08 64
Listas Encadeadas: Exercícios
Elabore um procedimento que dado um valor inteiro
qualquer, insira um novo nó em uma lista circular
duplamente encadeada com este valor caso o mesmo ainda não exista na lista, em ordem CRESCENTE, ou seja, sempre entre um nó contendo um valor menor e outro contendo um valor maior que o valor a ser inserido.
Elabore um procedimento que dado um valor inteiro
qualquer, elimine um nó de uma lista circular