Listas Duplamente Encadeadas Como vimos, uma lista...

Preview:

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++;

}

Recommended