ine5408 estruturas de dados - moodle ufsc · extensões do conceito de lista encadeada • a idéia...
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)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)Caso especial: Fila Unitária
1
uva
info próximo
tam início fim
Não preciso de uma variável auxiliar sai.
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í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çã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• 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.