Upload
lethu
View
227
Download
0
Embed Size (px)
Citation preview
228
Listas Duplamente Encadeadas
Como vimos, uma lista circular possui vantagens sobre uma lista linear, contudo esta ainda possui limitações.
Por exemplo, não podemos percorrê-la no sentido contrário ou ainda para inserirmos ou retirarmos um k-ésimoelemento temos que ter um ponteiro para seu antecessor.
Com o objetivo de sanar estas limitações surgiram as listas duplamente encadeadas.
229
Listas Duplamente Encadeadas
Em uma lista duplamente encadeadaos elementos possuem três campos: o campo inf o qual contém a informação, o campo ant que possui um ponteiro para o elemento antecessor e o campo prox que é uma referência para o elemento que sucede.
L
λλλλ
ant
λλλλ
prox
inf
230
Listas Duplamente EncadeadasDefiniremos agora o TAD LISTA_DUP_ENC:typedef struct nodo{
int inf;struct nodo * ant;struct nodo * prox;
}NODO;typedef NODO * LISTA_DUP_ENC;void cria_lista (LISTA_DUP_ENC *);int eh_vazia (LISTA_DUP_ENC);int tam (LISTA_DUP_ENC);void ins (LISTA_DUP_ENC *, int, int);int recup (LISTA_DUP_ENC, int);void ret (LISTA_DUP_ENC *, int);
231
void cria_lista (LISTA_DUP_ENC *pl){
*pl=NULL;}int eh_vazia (LISTA_DUP_ENC l){
return (l == NULL);}int tam (LISTA_DUP_ENC l){
int cont;for (cont=0; l!= NULL; cont++)
l = l->prox;return (cont); }
232
Esquema do processo da inserção de um nó da lista duplamente encadeada. (situação um)
Listas Duplamente Encadeadas
L
Novo
v. . .
L
Nodo 1
v. . .
233
Esquema do processo da inserção de um nó da lista duplamente encadeada. (situação dois)
Listas Duplamente Encadeadas
L
Nodo 1 Nodo 2 Nodo 3
Novo
v
..
.X
L
Nodo 2 Nodo 3 Nodo 4
Nodo 1
v
..
.
234
Esquema do processo da inserção de um nó da lista duplamente encadeada. (situação três)
Listas Duplamente Encadeadas
L
Nodo 1 Nodo 2
Novo
v
..
.
L
Nodo 1 Nodo 2
Nodo 3
v
..
.
235
Esquema do processo da inserção de um nó da lista duplamente encadeada. (situação quatro)
Listas Duplamente Encadeadas
L
Nodo 1 Nodo 2 Nodo 3
Novo
v
.. XX
L
Nodo 1 Nodo 3 Nodo 4
Nodo 2
v
..
236
void ins (LISTA_DUP_ENC *pl, int v, int k){
NODO *novo;if (k < 1 || k > tam(*pl)+1){
printf ("\nERRO! Posição invalida parainsercao.\n");exit (1);
}novo = (NODO *) malloc (sizeof(NODO));if (!novo){
printf ("\nERRO! Memoria insuficiente!\n");exit (2); }
237
novo->inf = v;if (k==1){
novo->ant = NULL;novo->prox = *pl;*pl = novo;if ((*pl)->prox)
(*pl)->prox->ant=novo;}else{
LISTA_DUP_ENC aux;for (aux=*pl; k>2; aux=aux->prox, k--);
238
novo->prox = aux->prox;aux->prox = novo; novo->ant=aux;if (novo->prox)
novo->prox->ant=novo;}
}
239
int recup (LISTA_DUP_ENC l, int k){
if (k < 1 || k > tam(l)){
printf ("\nERRO! Consulta invalida.\n");exit (3);
}for (;k>1;k--)
l=l->prox;return (l->inf);
}
240
Esquema do processo da retirada de um nó da lista duplamente encadeada. (situação um)
Listas Duplamente Encadeadas
L
Nodo 1
. . .
L
Aux
.
X
241
Esquema do processo da retirada de um nó da lista duplamente encadeada. (situação dois)
Listas Duplamente Encadeadas
L
Nodo 1 Nodo 2 Nodo 3Aux
..X
X
L
Nodo 1 Nodo 2
..
242
Esquema do processo da retirada de um nó da lista duplamente encadeada. (situação três)
Listas Duplamente Encadeadas
L
Nodo 1 Nodo 2 Nodo 3
Aux
..X
L
Nodo 1 Nodo 2
..
243
Esquema do processo da retirada de um nó da lista duplamente encadeada. (situação quatro)
Listas Duplamente Encadeadas
L
Nodo 1 Nodo 2 Nodo 3
Aux
..X
X
L
Nodo 1 Nodo 2
..
244
void ret (LISTA_DUP_ENC *pl, int k){
NODO *aux;if (k < 1 || k > tam(*pl)){
printf ("\nERRO! Posição invalida pararetirada.\n");exit (4);
}if (k==1){
aux = *pl;*pl = aux->prox;
245
if (*pl)(*pl)->ant=NULL;
free (aux);}else{
for (aux=(*pl)->prox; k>2; k--, aux=aux->prox);aux->ant->prox = aux->prox;if (aux->prox)
aux->prox->ant = aux->ant;free (aux);
}}
246
Implemente, no TAD LISTA_DUP_ENC, a seguinte operação:
void inverter_lista (LISTA_DUP_ENC *pl);
a qual recebe uma referência para uma lista duplamente encadeada e inverte a ordem de seus elementos.
Listas Duplamente Encadeadas – Exercício
248
Listas Duplamente Encadeadas
Também podemos construir listas circulares duplamente encadeadasou listas circulares duplamente encadeadas com nó cabeçalho.
2
Lista circular duplamente encadeada
Lista circular duplamente encadeada com nó cabeçalho
249
Listas Duplamente EncadeadasPara uma melhor fixação definiremos agora o
TAD LISTA_CIR_DUP_ENC_ NC.typedef struct nodo{
int inf;struct nodo * ant;struct nodo * prox;
}NODO;typedef NODO * LISTA_CIR_DUP_ENC_NC;void cria_lista (LISTA_CIR_DUP_ENC_NC *);int eh_vazia (LISTA_CIR_DUP_ENC_NC);int tam (LISTA_CIR_DUP_ENC_NC);void ins (LISTA_CIR_DUP_ENC_NC, int, int);int recup (LISTA_CIR_DUP_ENC_NC, int);void ret (LISTA_CIR_DUP_ENC_NC, int);
250
void cria_lista (LISTA_CIR_DUP_ENC_NC *pl){
NODO *novo;novo = (NODO *) malloc (sizeof(NODO));if (!novo){
printf ("\nERRO! Memoria insuficiente!\n");exit (2);
}novo->inf=0;*pl=novo->ant=novo->prox=novo;
}
251
int eh_vazia (LISTA_CIR_DUP_ENC_NC l){
return (l->inf == 0);}
int tam (LISTA_CIR_DUP_ENC_NC l){
return (l->inf);}
252
Esquema do processo da inserção de um nó da lista circular duplamente encadeada com nó cabeçalho.
Listas Duplamente Encadeadas
2
L
NC Nodo 1 Nodo 2 Novo
X
X
v
3
L
NC Nodo 1 Nodo 2 Nodo 3
v
253
void ins (LISTA_CIR_DUP_ENC_NC l, int v, int k){
LISTA_CIR_DUP_ENC_NC aux, novo;if (k < 1 || k > tam(l)+1){
printf ("\n%d %d\n",tam(l)+1,k);printf ("\nERRO! Posição invalida para
insercao.\n");exit (1);
}novo = (NODO *) malloc (sizeof(NODO));if (!novo){
printf ("\nERRO! Memoria insuficiente!\n");exit (2);
}
254
novo->inf = v;for (aux=l; k>1; aux=aux->prox, k--);novo->prox = aux->prox;novo->ant = aux; aux->prox = novo;novo->prox->ant=novo;l->inf++;
}