listas duplamente encadeadas como vimos, uma lista...
TRANSCRIPT
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++;
}