ine5408 estruturas de dados - moodle ufsc · extensões do conceito de lista encadeada • a idéia...

58
INE5408 Estruturas de Dados Listas Encadeadas - Pilhas encadeadas - Filas encadeadas - Listas duplamente encadeadas

Upload: lyduong

Post on 23-Dec-2018

223 views

Category:

Documents


0 download

TRANSCRIPT

INE5408Estruturas de Dados

Listas Encadeadas

- Pilhas encadeadas- Filas encadeadas- Listas duplamente encadeadas

Extensões do conceito de Lista Encadeada

• A idéia da Lista Encadeadavista até agora é o modelomais geral e simples;

• pode ser especializada e extendida das mais variadasformas:

– Especializada:• Pilhas encadeadas• Filas

– Extendida:• Listas Duplamente Encadeadas• Listas Circulares Simples e

Duplas

3altura topo

melão

info próximo

maçã

info próximo

uva

info próximo

Pilha Encadeada

Pilhas Encadeadas• São pilhas onde os elementos são

encadeados;– não há estouro de pilha;– como o acesso de dados na pilha

é puramente seqüencial, não háperda de eficiência.

• Existem apenas duas operações:– Empilhar: equivale a adicionar no

início.– Desempilhar: equivale a retirar do

início.• É a forma como tradicionalmente

pilhas são implementadas.

3altura topo

melão

info próximo

maçã

info próximo

uva

info próximo

Pilha Encadeada

Filas• A Fila é uma estrutura de dados que simula uma fila

da vida real.• Possui duas operações básicas:

– incluir no fim da fila;– retirar do começo da fila;– chamada de Estrutura-FIFO:

First-In, First-Out - O primeiro que entrou é o primeiro a sair…

Fila

Filas• É uma estrutura de dados importantíssima para:

– gerência de dados/processos por ordem cronológica:• Fila de impressão em uma impressora de rede;• Fila de pedidos de uma expedição ou tele-entrega.

– simulação de processos seqüenciais:• chão de fábrica: fila de camisetas a serem estampadas;• comércio: simulação de fluxo de um caixa de

supermercado;• tráfego: simulação de um cruzamento com um semáforo.

Fila

Filas• É uma estrutura de dados importantíssima para:

– gerência de dados/processos por ordem cronológica:• Fila de impressão em uma impressora de rede;• Fila de pedidos de uma expedição ou tele-entrega.

– simulação de processos seqüenciais:• chão de fábrica: fila de camisetas a serem estampadas;• comércio: simulação de fluxo de um caixa de

supermercado;• tráfego: simulação de um cruzamento com um semáforo.

Fila

Filas• É uma estrutura de dados importantíssima para:

– gerência de dados/processos por ordem cronológica:• Fila de impressão em uma impressora de rede;• Fila de pedidos de uma expedição ou tele-entrega.

– simulação de processos seqüenciais:• chão de fábrica: fila de camisetas a serem estampadas;• comércio: simulação de fluxo de um caixa de

supermercado;• tráfego: simulação de um cruzamento com um semáforo.

Fila

Filas• É uma estrutura de dados importantíssima para:

– gerência de dados/processos por ordem cronológica:• Fila de impressão em uma impressora de rede;• Fila de pedidos de uma expedição ou tele-entrega.

– simulação de processos seqüenciais:• chão de fábrica: fila de camisetas a serem estampadas;• comércio: simulação de fluxo de um caixa de

supermercado;• tráfego: simulação de um cruzamento com um semáforo.

Fila

Filas• É uma estrutura de dados importantíssima para:

– gerência de dados/processos por ordem cronológica:• Fila de impressão em uma impressora de rede;• Fila de pedidos de uma expedição ou tele-entrega.

– simulação de processos seqüenciais:• chão de fábrica: fila de camisetas a serem estampadas;• comércio: simulação de fluxo de um caixa de

supermercado;• tráfego: simulação de um cruzamento com um semáforo.

Fila

Filas: representação• Extensão da lista encadeada:

– referenciamos o últimoelemento também;

– adicionamos no fim;– excluímos do início.

3

melão

info próximo

maçã

info próximo

uva

info próximo

tam início fim Fila

Elemento de Fila

Pseudo-código:

tipo tFila {tElemento *início;tElemento *fim;inteiro tamanho;

};

Algoritmo CriaFilatFila* FUNÇÃO criaFila()

//Retorna ponteiro para uma nova cabeça de fila ou NULO.variáveis

tFila *aFila;início

aFila <- aloque(tFila);SE (aFila ~= NULO) ENTÃO

//Só posso inicializar se consegui alocar.aFila->tamanho <- 0;aFila->início <- NULO;aFila->fim <- NULO;

FIM SERETORNE(aFila);

fim;

Algoritmo Adiciona (Fila)

2

melão

info próximo

maçã

info próximo

uva

info próximo

tam início fim

Algoritmo Adiciona (Fila)

2

melão

info próximo

maçã

info próximo

uva

info próximo

tam início fim

Algoritmo Adiciona (Fila)

3

melão

info próximo

maçã

info próximo

uva

info próximo

tam início fim

Algoritmo Adiciona (Fila)Caso especial: Fila Vazia

0

tam início fim

uva

info próximo

Algoritmo Adiciona (Fila)Caso especial: Fila Vazia

1

tam início fim

uva

info próximo

Algoritmo Adiciona (Fila)Inteiro FUNÇÃO adiciona(tFila *aFila, TipoInfo *dado)

variáveistElemento *novo; //Variável auxiliar para o novo elemento.

inícionovo <- aloque(tElemento);SE (novo = NULO) ENTÃO

RETORNE(ERROFILACHEIA)SENÃO

SE filaVazia(aFila) ENTÃOaFila->início <- novo

SENÃOaFila->fim->próximo <- novo;

FIM SEnovo->próximo <- NULO;novo->info <- dado;aFila->fim <- novo;aFila->tamanho <- aFila->tamanho + 1;RETORNE(aFila->tamanho);

FIM SEfim;

Algoritmo Retira (Fila)

3

melão

info próximo

maçã

info próximo

uva

info próximo

tam início fim

sai

Algoritmo Retira (Fila)

3

melão

info próximo

maçã

info próximo

uva

info próximo

tam início fim

sai

Algoritmo Retira (Fila)

2

maçã

info próximo

uva

info próximo

tam início fim

Algoritmo Retira (Fila)Caso especial: Fila Unitária

1

uva

info próximo

tam início fim

Não preciso de uma variável auxiliar sai.

Algoritmo Retira (Fila)Caso especial: Fila Unitária

0

tam início fim

Algoritmo RetiraDoInício (Fila)TipoInfo* FUNÇÃO retiraDoInício(tFila *aFila)

//Elimina o primeiro elemento de uma fila.//Retorna a informação do elemento eliminado ou NULO.variáveis

tElemento *saiu; //Variável auxiliar para o primeiro elemento.TipoInfo *volta; //Variável auxiliar para o dado retornado.

inícioSE (filaVazia(aFila)) ENTÃORETORNE(NULO)

SENÃOsaiu <- aFila->início;volta <- saiu->info;aFila->início <- saiu->próximo; //Se SAIU for o único, próximo é NULO e está certo.SE (aFila->tamanho = 1) ENTÃO

//Fila unitária: devo anular o fim também.aFila->fim <- NULO;

FIM SEaFila->tamanho <- aFila->tamanho - 1;LIBERE(saiu);RETORNE(volta);

FIM SEfim;

Exercício com Filas• Implemente o TAD Fila Encadeada com as suas duas

operações de manipulação;• implemente um programa principal de aplicação que

utilize uma fila para:– ler dados de pedidos de solicitação de conserto de

computadores da marca HAL pela sua assistência técnicaAssistHAL;

– utilize o seguinte TipoInfo: nome do solicitante, telefone, data da entrega (inserida automaticamente), modelo do computador e valor do conserto, que é um valor chutado.

• Após cadastrado um pedido, o sistema deveráinformar quando o solicitante poderá contar com o computador pronto, sendo que:– a oficina AssistHAL leva em média duas semanas por

pedido.

Listas Duplamente Encadeadas• A Lista Encadeada e a Fila Encadeada possuem a

desvantagem de somente podermos caminhar emuma direção:– vimos que para olhar um elemento pelo qual “acabamos de

passar” precisamos de uma variável auxiliar “anterior”;– para olhar outros elementos ainda anteriores não temos

nenhum meio, a não ser começar de novo.• A Lista Duplamente Encadeada é uma estrutura de

lista que permite deslocamento em ambos ossentidos:– útil para representar conjuntos de eventos ou objetos a

serem percorridos em dois sentidos;– ex.: itinerários de ônibus, trem ou avião;– útil também quando realizamos uma busca aproximada e

nos movemos para a frente e para trás.

Listas Duplamente Encadeadas - Modelagem

3tam dados

melão

doce

caro

maçã

azeda

cara

uva

irkh

barata

ant info suc info suc info sucant ant

Modelagem: Cabeça de ListaDupla

• Necessitamos:– um ponteiro para o primeiro elemento da lista;– um inteiro para indicar quantos elementos a lista

possui.

• Pseudo-código:tipo tListaDupla {

tElementoDuplo *dados;inteiro tamanho;

};

Modelagem: Elemento de ListaDupla

• Necessitamos:– um ponteiro para o elemento anterior na lista;– um ponteiro para o elemento sucessor na lista;– um ponteiro para a informação que vamos

armazenar.

• Pseudo-código:tipo tElementoDuplo {

tElementoDuplo *anterior;tElementoDuplo *sucessor;TipoInfo *info;

};

Modelagem da Lista Duplamente Encadeada

• Aspecto Funcional:– colocar e retirar dados da lista;– testar se a lista está vazia e outros testes;– inicializá-la e garantir a ordem dos elementos.

3tam dados

melão

doce

caro

maçã

azeda

cara

uva

irkh

barata

ant info suc ant info suc ant info suc

Modelagem da Lista Duplamente Encadeada

• Operações - colocar e retirar dados da lista:– AdicionaDuplo(listaDupla, dado)– AdicionaNoInícioDuplo(listaDupla, dado)– AdicionaNaPosiçãoDuplo(listaDupla, dado,

posição)– AdicionaEmOrdemDuplo(listaDupla, dado)

– RetiraDuplo(listaDupla)– RetiraDoInícioDuplo(listaDupla)– RetiraDaPosiçãoDuplo(listaDupla, posição)– RetiraEspecíficoDuplo(listaDupla, dado)

Modelagem da Lista Duplamente Encadeada

• Operações - testar a lista e outros testes:– ListaVaziaDuplo(listaDupla)– PosiçãoDuplo(listaDupla, dado)– ContémDuplo(listaDupla, dado)

• Operações - inicializar ou limpar:– CriaListaDupla()– DestróiListaDupla(listaDupla)

Algoritmo CriaListaDuplatListaDupla* FUNÇÃO criaListaDupla()

//Retorna ponteiro para uma nova cabeça de lista ou NULO.variáveis

tListaDupla *aLista;início

aLista <- aloque(tListaDupla);SE (aLista ~= NULO) ENTÃO

//Só posso inicializar se consegui alocar.aLista->tamanho <- 0;aLista->dados <- NULO;

FIM SERETORNE(aLista);

fim;

Algoritmo ListaVaziaDuploBooleano FUNÇÃO listaVaziaDuplo(tListaDupla

*aLista)início

SE (aLista->tamanho = 0) ENTÃORETORNE(Verdadeiro)

SENÃORETORNE(Falso);

fim;

Algoritmo AdicionaNoInícioDuplo• Procedimento:

– testamos se é possível alocar um elemento;– fazemos o sucessor deste novo elemento ser o

primeiro da lista;– fazemos o seu antecessor ser NULO;– fazemos a cabeça de lista apontar para o novo

elemento.• Parâmetros:

– o dado a ser inserido;– a ListaDupla.

Algoritmo AdicionaNoInícioDuplo

novo

2tam dados

maçã

azeda

cara

uva

irkh

barata

melão

doce

caro

ant info suc ant info suc info sucant

Algoritmo AdicionaNoInícioDuplo

novo

2tam dados

maçã

azeda

cara

uva

irkh

barata

melão

doce

caro

ant info suc info suc info sucant ant

Caso novo->suc não seja nulo...

Faço novo->suc->ant ser novo...

Algoritmo AdicionaNoInícioDuplo

novo

3tam dados

maçã

azeda

cara

uva

irkh

barata

melão

doce

caro

ant info suc info suc info sucant ant

Algoritmo AdicionaNoInícioDuploInteiro FUNÇÃO adicionaNoInícioDuplo(tListaDupla *aLista,

TipoInfo *dado)variáveis

tElementoDuplo *novo; //Variável auxiliar para o novo elemento.início

novo <- aloque(tElementoDuplo);SE (novo = NULO) ENTÃO

RETORNE(ERROLISTACHEIA)SENÃO

novo->suc <- aLista->dados;novo->ant <- NULO;novo->info <- dado;aLista->dados <- novo;SE (novo->suc ~= NULO) ENTÃO

novo->suc->ant <- novo;FIM SE;aLista->tamanho <- aLista->tamanho + 1;RETORNE(1);

FIM SEfim;

Algoritmo RetiraDoInícioDuplo• Procedimento:

– testamos se há elementos;– decrementamos o tamanho;– se o elemento possuir sucessor, o

antecessor do sucessor será NULO;– liberamos a memória do elemento;– devolvemos a informação.

• Parâmetros:– a ListaDupla.

Algoritmo RetiraDoInícioDuplo

saiu

volta

3tam dados

maçã

azeda

cara

uva

irkh

barata

melão

doce

caro

ant info suc info suc info sucant ant

Algoritmo RetiraDoInícioDuplo

saiu

volta

2tam dados

maçã

azeda

cara

uva

irkh

barata

melão

doce

caro

ant info suc info suc info sucant ant

Algoritmo RetiraDoInícioDuplo

saiu

volta

2tam dados

maçã

azeda

cara

uva

irkh

barata

melão

doce

caro

ant info suc info suc info sucant ant

Algoritmo RetiraDoInícioDuplo

2tam dados

maçã

azeda

cara

uva

irkh

barata

ant info suc info sucant

Algoritmo RetiraDoInícioDuploTipoInfo* FUNÇÃO retiraDoInícioDuplo(tListaDupla *aLista)

//Elimina o primeiro elemento de uma lista duplamente encadeada.//Retorna a informação do elemento eliminado ou NULO.variáveis

tElementoDuplo *saiu; //Variável auxiliar para o primeiro elemento.TipoInfo *volta; //Variável auxiliar para o dado retornado.

inícioSE (listaVaziaDuplo(aLista)) ENTÃO

RETORNE(NULO)SENÃO

saiu <- aLista->dados;volta <- saiu->info;aLista->dados <- saiu->suc;SE (aLista->dados ~= NULO) ENTÃO

aLista->dados->ant <- NULO;FIM SEaLista->tamanho <- aLista->tamanho - 1;LIBERE(saiu);RETORNE(volta);

FIM SEfim;

Algoritmo AdicionaNaPosiçãoDuplo

• Praticamente idêntico à lista encadeada;• procedimento:

– testamos se a posição existe e se é possível alocar elemento;

– caminhamos até a posição;– adicionamos o novo dado na posição;– incrementamos o tamanho.

• Parâmetros:– o dado a ser inserido;– a posição onde inserir;– a Lista.

Algoritmo AdicionaNaPosiçãoInteiro FUNÇÃO adicionaNaPosiçãoDuplo(tListaDupla *aLista, TipoInfo *info, inteiro posição)

//Adiciona novo elemento na posição informada.//Retorna o novo número de elementos da lista ou erro.variáveis

tElementoDuplo *novo, *anterior; //Ponteiros auxiliares.início

SE (posição > aLista->tamanho + 1 OU posição < 1) ENTÃORETORNE(ERROPOSIÇÃO)

SENÃOSE (posição = 1) ENTÃO

RETORNE(adicionaNoInícioDuplo(aLista, info)SENÃO

novo <- aloque(tElemento);SE (novo = NULO) ENTÃO

RETORNE(ERROLISTACHEIA)SENÃO

anterior <- aLista->dados;REPITA (posição - 2) VEZES

anterior <- anterior->suc;novo->suc <- anterior->suc;SE (novo->suc ~= NULO ENTÃO //Se o novo não é o último da lista…

novo->suc->ant <- novo; //Seto o antecessor do sucessor do novo.FIM SEnovo->info <- info;anterior->suc <- novo;novo->ant <- anterior;aLista->tamanho <- aLista->tamanho + 1;RETORNE(aLista->tamanho);

FIM SEFIM SE

FIM SEfim;

Algoritmo RetiraDaPosiçãoDuplo• Mais simples que na Lista Encadeada;• procedimento:

– testamos se a posição existe;– caminhamos até a posição;– retiramos o dado da posição;– decrementamos o tamanho.

• Parâmetros:– a posição de onde retirar;– a Lista.

Algoritmo RetiraDaPosiçãoDuplo

4

maçã

azeda

cara

uva

irkh

barata

melão

doce

caro

jaca

irkh

barata

eliminar

Posições > 1

Algoritmo RetiraDaPosiçãoDuplo

Posições > 1

4

maçã

azeda

cara

uva

irkh

barata

melão

doce

caro

jaca

irkh

barata

eliminar

Algoritmo RetiraDaPosiçãoDuplo

Posições > 1

3

maçã

azeda

cara

uva

irkh

barata

melão

doce

caro

jaca

irkh

barata

eliminar

Algoritmo RetiraDaPosiçãoDuplo

Posições > 1

3

maçã

azeda

cara

melão

doce

caro

jaca

irkh

barata

Algoritmo RetiraDaPosiçãoDuploTipoInfo* FUNÇÃO retiraDaPosiçãoDuplo(tListaDupla *aLista, inteiro posição)

//Elimina o elemento da posição informada.//Retorna a informação do elemento eliminado ou NULO.variáveis

tElementoDuplo *anterior, *eliminar; //Variável auxiliar para elemento.TipoInfo *volta; //Variável auxiliar para o dado retornado.

inícioSE (posição > aLista->tamanho OU posição < 1) ENTÃO

RETORNE(NULO)SENÃO

SE (posição = 1) ENTÃORETORNE(retiraDoInícioDuplo(aLista))

SENÃOanterior <- aLista->dados;REPITA (posição - 2) VEZES

anterior <- anterior->suc;eliminar <- anterior->suc;volta <- eliminar->info;anterior->suc <- eliminar->suc;SE eliminar->suc ~= NULO ENTÃO

eliminar->suc->ant <- anterior;FIM SEaLista->tamanho <- aLista->tamanho - 1;LIBERE(eliminar);RETORNE(volta);

FIM SEFIM SE

fim;

Algoritmo AdicionaEmOrdemDuplo

• Idêntico à lista encadeada;• procedimento:

– necessitamos de uma função para comparar os dados (maior);

– procuramos pela posição onde inserir comparando dados;

– chamamos adicionaNaPosiçãoDuplo().• Parâmetros:

– o dado a ser inserido.– a ListaDupla.

Algoritmo AdicionaEmOrdemDuploInteiro FUNÇÃO adicionaEmOrdemDuplo(tListaDupla *aLista, TipoInfo *dado)

variáveistElementoDuplo *atual; //Variável auxiliar para caminhar.inteiro posição;

inícioSE (listaVaziaDupla(aLista)) ENTÃORETORNE(adicionaNoInícioDuplo(aLista, dado))

SENÃOatual <- aLista->dados;posição <- 1;ENQUANTO (atual->suc ~= NULO E maior(dado, atual->info)) FAÇA

//Encontrar posição para inserir.atual <- atual->suc;posição <- posição + 1;

FIM ENQUANTOSE maior(dado, atual->info) ENTÃO //Parou porque acabou a lista.RETORNE(adicionaNaPosiçãoDuplo(aLista,dado,posição + 1))

SENÃORETORNE(adicionaNaPosiçãoDuplo(aLista, dado, posição));

FIM SEFIM SE

fim;

Algoritmos restantesLista Duplamente EncadeadaPor conta do aluno:• operações de inclusão e exclusão:

– AdicionaDuplo(listaDupla, dado)– RetiraDuplo(listaDupla)– RetiraEspecíficoDuplo(listaDupla,

dado)• Operações - inicializar ou limpar:

– DestróiListaDupla(listaDupla)

Exercício de Implementação 6

Implemente uma Lista de Rotasutilizando Listas DuplamenteEncadeadas.

Exercício de Implementação 6• Este programa deverá gerenciar um conjunto de listas de

rotas/linhas de uma companhia de ônibus intermunicipal do Estado de Santa Catarina;

• todas as rotas se iniciam em Florianópolis;• cada rota possui um nome que a identifica de forma única, dado

pelo destino. Ex: "Imbituba“;• cada rota possui a lista de todas as cidades por onde o ônibus

passa, para ir de Florianópolis ao destino;• a rota de ônibus, ao retornar, passa pelos mesmos lugares.

Portanto, pode ser representada por uma lista duplamenteencadeada;

• o usuário deve poder escolher uma rota e poder navegar por ela, indo de cidade em cidade e voltando para a cidade anterior, usando para tanto as teclas de seta à esquerda e seta à direita;

• cada nodo representando uma cidade possui, além do nome, um texto descrevendo alguma característica desta cidade. Ex.: "Láquebram as melhores ondas da costa sul do Brasil". Este texto émostrado quando se visita um nodo.

Exercício de Implementação 6• Implemente o programa de rotas como uma

lista de listas;• a lista que contém todas as rotas pode ser

uma lista encadeada ou uma lista em vetor;• cada lista que representa uma rota deve ser

uma lista duplamente encadeada;• implemente tanto a lista de listas como a lista

duplamente encadeada como um TAD separado com todas as suas funções.