A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

INE5408 Estruturas de Dados

Apresentações semelhantes


Apresentação em tema: "INE5408 Estruturas de Dados"— Transcrição da apresentação:

1 INE5408 Estruturas de Dados
Listas Encadeadas Simples

2 Listas com Vetores: Desvantagens
Tamanho máximo fixo; mesmo vazias ocupam um grande espaço de memória: mesmo que utilizemos um vetor de ponteiros, se quisermos prever uma lista de elementos, teremos bytes desperdiçados; operações podem envolver muitos deslocamentos de dados: inclusão em uma posição ou no início; exclusão em uma posição ou no início. 24 20 5 4 24 89 89 12 4 12 55 4 55

3 Listas Encadeadas São listas onde cada elemento está armazenado em um TAD chamado elemento de lista; cada elemento de lista referencia o próximo e só é alocado dinamicamente quando necessário; para referenciar o primeiro elemento utilizamos um TAD cabeça de lista.

4 Listas Encadeadas Cabeça de Lista 5 Elemento de Lista melão maçã uva
nro dados Cabeça de Lista 5 info próximo info próximo info próximo melão maçã uva Elemento de Lista

5 Modelagem: Cabeça de Lista
Necessitamos: um ponteiro para o primeiro elemento da lista; um inteiro para indicar quantos elementos a lista possui. Pseudo-código: tipo tLista { tElemento *dados; inteiro tamanho; };

6 Modelagem: Elemento de Lista
Necessitamos: um ponteiro para o próximo elemento da lista; um campo do tipo da informação que vamos armazenar. Pseudo-código: tipo tElemento { tElemento *próximo; tipo-que-eu-vou-usar-nesta-aplicação info; };

7 Listas Encadeadas: Modelagem
Para tornar todos os algoritmos da lista mais genéricos, fazemos o campo info ser um ponteiro para um elemento de informação. nro dados 3 info próximo info próximo info próximo melão maçã uva doce azeda irkh Elemento de Informação (tipoInfo) caro cara barata

8 Modelagem: Elemento de Lista
Pseudo-código do TAD elemento de lista: tipo tElemento { tElemento *próximo; TipoInfo *info; }; Local: lista.h Ao invés de colocar a Informação no elemento de lista, usamos um ponteiro para ela.

9 Modelagem: Elemento de Dados
Pseudo-código do TAD TipoInfo: tipo TipoInfo { tipo-do-campo1 campo1; tipo-do-campo2 campo2; tipo-do-campoN campoN; } Local: info.h

10 Modelagem: Elemento de Dados
Razões para a modelagem do TipoInfo: vamos na maioria dos algoritmos trabalhar com algum elemento de informação; se este elemento é somente um ponteiro para um TipoInfo, não importando o que este seja, teremos algoritmos totalmente genéricos: posso usar o mesmo código de lista para muitas aplicações diferentes simplesmente recompilando. somente modifico um único headerfile: info.h Desvantagens: o algoritmo de destruição da lista torna-se mais complexo. TipoInfo necessita de um destrutor próprio

11 Modelagem: Aspecto Funcional
3 Categorias de Operações: colocar e retirar dados da lista; testar se a lista está vazia e outros testes; inicializá-la e garantir a ordem dos elementos. 5 melão doce caro maçã azeda cara uva irkh barata

12 Modelagem: Operações da Lista
Operações - colocar e retirar dados da lista: Adiciona(lista, dado) AdicionaNoInício(lista, dado) AdicionaNaPosição(lista, dado, posição) AdicionaEmOrdem(lista, dado) Retira(lista) RetiraDoInício(lista) RetiraDaPosição(lista, posição) RetiraEspecífico(lista, dado)

13 Modelagem: Operações da Lista
Operações - testar a lista e outros testes: ListaVazia(lista) Posição(lista, dado) Contém(lista, dado) Operações - inicializar ou limpar: CriaLista() DestróiLista(lista)

14 Novidades na Modelagem das Operações
Lista é um Parâmetro da Operação Operação é definida de forma genérica Operação é realizada sobre uma determinada lista Qualquer nº de listas é possível Analogia com POO: método/função-membro Padrão de codificação: 1º parâmetro é sempre o TAD sobre o qual a operação é realizada

15 Novidades na Modelagem das Operações
Lista é passada sempre por referência Passamos um ponteiro para a lista Lista está armazenada em uma variável global ou em outro lugar Razões Operações modificam a lista Temos de trabalhar sobre a mesma lista dentro e fora das operações e não sobre uma cópia passada à função pelo stack

16 Algoritmo CriaLista Lista* FUNÇÃO criaLista() variáveis Lista *aLista;
//Retorna ponteiro para uma nova cabeça de lista ou NULO. variáveis Lista *aLista; início aLista <- aloque(Lista); SE (aLista ~= NULO) ENTÃO //Só posso inicializar se consegui alocar. aLista->tamanho <- 0; aLista->dados <- NULO; FIM SE RETORNE(aLista); fim;

17 Algoritmo CriaLista Lista* FUNÇÃO criaLista() variáveis Lista *aLista;
//Retorna ponteiro para uma nova cabeça de lista ou NULO. variáveis Lista *aLista; início aLista <- aloque(Lista); SE (aLista ~= NULO) ENTÃO //Só posso inicializar se consegui alocar. aLista->tamanho <- 0; aLista->dados <- NULO; FIM SE RETORNE(aLista); fim;

18 Algoritmo CriaLista Lista* FUNÇÃO criaLista() variáveis Lista *aLista;
//Retorna ponteiro para uma nova cabeça de lista ou NULO. variáveis Lista *aLista; início aLista <- aloque(Lista); SE (aLista ~= NULO) ENTÃO //Só posso inicializar se consegui alocar. aLista->tamanho <- 0; aLista->dados <- NULO; FIM SE RETORNE(aLista); fim;

19 Algoritmo ListaVazia Booleano FUNÇÃO listaVazia(Lista *aLista) início
SE (aLista->tamanho = 0) ENTÃO RETORNE(Verdadeiro) SENÃO RETORNE(Falso); fim; Um algoritmo ListaCheia não existe aqui; verificar se houve espaço na memória para um novo elemento será responsabilidade de cada operação de adição.

20 Algoritmo AdicionaNoInício
Procedimento: testamos se é possível alocar um elemento; fazemos o próximo deste novo elemento ser o primeiro da lista; fazemos a cabeça de lista apontar para o novo elemento. Parâmetros: O tipo info (dado) a ser inserido; a Lista.

21 Algoritmo AdicionaNoInício
2 novo melão doce caro maçã uva azeda irkh cara barata

22 Algoritmo AdicionaNoInício
3 2 melão doce caro maçã uva azeda irkh cara barata

23 Algoritmo AdicionaNoInício
Inteiro FUNÇÃO adicionaNoInício(Lista *aLista, TipoInfo *dado) variáveis tElemento *novo; //Variável auxiliar. início novo <- aloque(tElemento); SE (novo = NULO) ENTÃO RETORNE(ErroListaCheia); SENÃO novo->próximo <- aLista->dados; novo->info <- dado; aLista->dados <- novo; aLista->tamanho <- aLista->tamanho + 1; RETORNE(1); FIM SE fim;

24 Algoritmo AdicionaNoInício
Inteiro FUNÇÃO adicionaNoInício(Lista *aLista, TipoInfo *dado) variáveis tElemento *novo; //Variável auxiliar. início novo <- aloque(tElemento); SE (novo = NULO) ENTÃO RETORNE(ErroListaCheia); SENÃO novo->próximo <- aLista->dados; novo->info <- dado; aLista->dados <- novo; aLista->tamanho <- aLista->tamanho + 1; RETORNE(1); FIM SE fim;

25 Algoritmo AdicionaNoInício
Inteiro FUNÇÃO adicionaNoInício(Lista *aLista, TipoInfo *dado) variáveis tElemento *novo; //Variável auxiliar. início novo <- aloque(tElemento); SE (novo = NULO) ENTÃO RETORNE(ErroListaCheia); SENÃO novo->próximo <- aLista->dados; novo->info <- dado; aLista->dados <- novo; aLista->tamanho <- aLista->tamanho + 1; RETORNE(1); FIM SE fim;

26 Algoritmo RetiraDoInício
Procedimento: testamos se há elementos; decrementamos o tamanho; liberamos a memória do elemento; devolvemos a informação. Parâmetros: a Lista.

27 Algoritmo RetiraDoInício
3 saiu melão doce caro volta maçã uva azeda irkh cara barata

28 Algoritmo RetiraDoInício
3 saiu melão doce caro volta maçã uva azeda irkh cara barata

29 Algoritmo RetiraDoInício
2 saiu volta melão maçã uva doce azeda irkh caro cara barata

30 Algoritmo RetiraDoInício
TipoInfo* FUNÇÃO retiraDoInício(Lista *aLista) //Elimina o primeiro elemento de uma lista. //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ício SE (listaVazia(aLista)) ENTÃO RETORNE(NULO); SENÃO saiu <- aLista->dados; volta <- saiu->info; aLista->dados <- saiu->próximo; aLista->tamanho <- aLista->tamanho - 1; LIBERE(saiu); RETORNE(volta); FIM SE fim;

31 Algoritmo EliminaDoInício
inteiro FUNÇÃO eliminaDoInício(Lista *aLista) //Elimina o primeiro elemento de uma lista e sua respectiva informação. //Retorna a posição do elemento eliminado ou erro. variáveis tElemento *saiu; //Variável auxiliar para o primeiro elemento. início SE (listaVazia(aLista)) ENTÃO RETORNE(ErroListaVazia); SENÃO saiu <- aLista->dados; aLista->dados <- saiu->próximo; aLista->tamanho <- aLista->tamanho - 1; LIBERE(saiu->info); LIBERE(saiu); RETORNE(aLista->tamanho + 1); FIM SE fim;

32 Algoritmo EliminaDoInício
Observe que a linha LIBERE(saiu->info) possui um perigo: se o TipoInfo for por sua vez um conjunto estruturado de dados com referências internas através de ponteiros (outra lista, por exemplo), a chamada à função LIBERE(saiu->info) só liberará o primeiro nível da estrutura (aquele apontado diretamente); tudo o que for referenciado através de ponteiros em info permanecerá em algum lugar da memória, provavelmente inatingível (garbage); para evitar isto pode-se criar uma função destrói(info) para o TipoInfo que será chamada no lugar de LIBERE.

33 Exemplo simplificado: Programa Principal
#inclua listaEnc.h variáveis tLista *devedores, *credores, *listaEscolhida; TipoInfo *dado; caracter opção; 1 Programa Principal 2 início 3 devedores <- criaLista(); 4 credores <- criaLista(); 5 opção <- ´´; 6 ENQUANTO (opção ~= ´f´) ENTÃO 7 escreveMenu(); 8 leia(opção); 9 CASO opção SEJA ´c´: listaEscolhida <- credores; ´d´: listaEscolhida <- devedores; ´i´: dado <- leiaInfo(); 13 adicionaNoInício(listaEscolhida, dado); -- FIM CASO -- FIM ENQUANTO -- fim;

34 StackPointer Topo da Pilha Memória logo após o início do programa, quando o fluxo de execução se encontra na linha #2. HeapPointer Topo da Área Alocável devedores, credores, listaEscolhida, dado, opção Variáveis estáticas (globais) Código objeto do Programa Sist.Operacional Base da Memória

35 StackPointer Topo da Pilha Memória logo após as 2 chamadas à função criaLista(), quando o fluxo de execução do programa se encontra na linha #5. HeapPointer Topo da Área Alocável Lista Lista devedores, credores, listaEscolhida, dado, opção Variáveis estáticas (globais) Código objeto do Programa Sist.Operacional Base da Memória

36 Memória imediatamente antes de retornar de uma chamada à função adicionaNoInício(), quando a listaEscolhida é a dos credores e o fluxo de execução do programa se encontra na última linha da função adicionaNoInício() e retornará ao programa principal para a linha #13. &progr. #13 lista dado novo StackPointer Topo da Pilha HeapPointer Topo da Área Alocável Elemento TipoInfo Lista Lista devedores, credores, listaEscolhida, dado, opção Variáveis estáticas (globais) Código objeto do Programa Sist.Operacional Base da Memória

37 Algoritmo AdicionaNaPosição
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.

38 Algoritmo AdicionaNaPosição
anterior 3 maçã maçã uva azeda azeda irkh cara cara barata novo melão doce caro

39 Algoritmo AdicionaNaPosição
anterior 4 maçã maçã uva azeda azeda irkh cara cara barata novo melão doce caro

40 Algoritmo AdicionaNaPosição
Inteiro FUNÇÃO adicionaNaPosição(tLista *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 tElemento *novo, *anterior; //Ponteiros auxiliares. início SE (posição > aLista->tamanho + 1) ENTÃO RETORNE(ErroPosição) SENÃO SE (posição = 1) ENTÃO RETORNE(adicionaNoInício(aLista, info); novo <- aloque(tElemento); SE (novo = NULO) ENTÃO RETORNE(ErroListaCheia); anterior <- aLista->dados; REPITA (posição - 2) VEZES anterior <- anterior->próximo; novo->próximo <- anterior->próximo; novo->info <- info; anterior->próximo <- novo; aLista->tamanho <- aLista->tamanho + 1; RETORNE(aLista->tamanho); FIM SE fim;

41 Algoritmo AdicionaNaPosição
Inteiro FUNÇÃO adicionaNaPosição(tLista *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 tElemento *novo, *anterior; //Ponteiros auxiliares. início SE (posição > aLista->tamanho + 1) ENTÃO RETORNE(ErroPosição) SENÃO SE (posição = 1) ENTÃO RETORNE(adicionaNoInício(aLista, info); novo <- aloque(tElemento); SE (novo = NULO) ENTÃO RETORNE(ErroListaCheia); anterior <- aLista->dados; REPITA (posição - 2) VEZES anterior <- anterior->próximo; novo->próximo <- anterior->próximo; novo->info <- info; anterior->próximo <- novo; aLista->tamanho <- aLista->tamanho + 1; RETORNE(aLista->tamanho); FIM SE fim;

42 Algoritmo AdicionaNaPosição
Inteiro FUNÇÃO adicionaNaPosição(tLista *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 tElemento *novo, *anterior; //Ponteiros auxiliares. início SE (posição > aLista->tamanho + 1) ENTÃO RETORNE(ErroPosição) SENÃO SE (posição = 1) ENTÃO RETORNE(adicionaNoInício(aLista, info); novo <- aloque(tElemento); SE (novo = NULO) ENTÃO RETORNE(ErroListaCheia); anterior <- aLista->dados; REPITA (posição - 2) VEZES anterior <- anterior->próximo; novo->próximo <- anterior->próximo; novo->info <- info; anterior->próximo <- novo; aLista->tamanho <- aLista->tamanho + 1; RETORNE(aLista->tamanho); FIM SE fim;

43 Algoritmo AdicionaNaPosição
Inteiro FUNÇÃO adicionaNaPosição(tLista *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 tElemento *novo, *anterior; //Ponteiros auxiliares. início SE (posição > aLista->tamanho + 1) ENTÃO RETORNE(ErroPosição) SENÃO SE (posição = 1) ENTÃO RETORNE(adicionaNoInício(aLista, info); novo <- aloque(tElemento); SE (novo = NULO) ENTÃO RETORNE(ErroListaCheia); anterior <- aLista->dados; REPITA (posição - 2) VEZES anterior <- anterior->próximo; novo->próximo <- anterior->próximo; novo->info <- info; anterior->próximo <- novo; aLista->tamanho <- aLista->tamanho + 1; RETORNE(aLista->tamanho); FIM SE fim;

44 Algoritmo RetiraDaPosição
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.

45 Algoritmo RetiraDaPosição
Posições > 1 anterior eliminar 4 melão doce caro maçã uva jaca azeda irkh irkh cara barata barata

46 Algoritmo RetiraDaPosição
Posições > 1 anterior eliminar 4 melão doce caro maçã uva jaca azeda irkh irkh cara barata barata

47 Algoritmo RetiraDaPosição
Posições > 1 anterior eliminar 4 melão doce caro maçã jaca azeda irkh cara barata

48 Algoritmo RetiraDaPosição
Posições > 1 anterior eliminar 3 melão doce caro maçã jaca azeda irkh cara barata

49 Algoritmo RetiraDaPosição
Posições > 1 3 melão doce caro maçã jaca azeda irkh cara barata

50 Algoritmo RetiraDaPosição
TipoInfo* FUNÇÃO retiraDaPosição(tLista *aLista, inteiro posição) //Elimina o elemento da posição de uma lista. //Retorna a informação do elemento eliminado ou NULO. variáveis tElemento *anterior, *eliminar; //Variável auxiliar para elemento. TipoInfo *volta; //Variável auxiliar para o dado retornado. início SE (posição > aLista->tamanho) ENTÃO RETORNE(NULO); SENÃO SE (posição = 1) ENTÃO RETORNE(retiraDoInício(aLista)); anterior <- aLista->dados; REPITA (posição - 2) VEZES anterior <- anterior->próximo; eliminar <- anterior->próximo; volta <- eliminar->info; anterior->próximo <- eliminar->próximo; aLista->tamanho <- aLista->tamanho - 1; LIBERE(eliminar); RETORNE(volta); FIM SE fim;

51 Algoritmo RetiraDaPosição
TipoInfo* FUNÇÃO retiraDaPosição(tLista *aLista, inteiro posição) //Elimina o elemento da posição de uma lista. //Retorna a informação do elemento eliminado ou NULO. variáveis tElemento *anterior, *eliminar; //Variável auxiliar para elemento. TipoInfo *volta; //Variável auxiliar para o dado retornado. início SE (posição > aLista->tamanho) ENTÃO RETORNE(NULO); SENÃO SE (posição = 1) ENTÃO RETORNE(retiraDoInício(aLista)); anterior <- aLista->dados; REPITA (posição - 2) VEZES anterior <- anterior->próximo; eliminar <- anterior->próximo; volta <- eliminar->info; anterior->próximo <- eliminar->próximo; aLista->tamanho <- aLista->tamanho - 1; LIBERE(eliminar); RETORNE(volta); FIM SE fim;

52 Algoritmo RetiraDaPosição
TipoInfo* FUNÇÃO retiraDaPosição(tLista *aLista, inteiro posição) //Elimina o elemento da posição de uma lista. //Retorna a informação do elemento eliminado ou NULO. variáveis tElemento *anterior, *eliminar; //Variável auxiliar para elemento. TipoInfo *volta; //Variável auxiliar para o dado retornado. início SE (posição > aLista->tamanho) ENTÃO RETORNE(NULO); SENÃO SE (posição = 1) ENTÃO RETORNE(retiraDoInício(aLista)); anterior <- aLista->dados; REPITA (posição - 2) VEZES anterior <- anterior->próximo; eliminar <- anterior->próximo; volta <- eliminar->info; anterior->próximo <- eliminar->próximo; aLista->tamanho <- aLista->tamanho - 1; LIBERE(eliminar); RETORNE(volta); FIM SE fim;

53 Algoritmo RetiraDaPosição
TipoInfo* FUNÇÃO retiraDaPosição(tLista *aLista, inteiro posição) //Elimina o elemento da posição de uma lista. //Retorna a informação do elemento eliminado ou NULO. variáveis tElemento *anterior, *eliminar; //Variável auxiliar para elemento. TipoInfo *volta; //Variável auxiliar para o dado retornado. início SE (posição > aLista->tamanho) ENTÃO RETORNE(NULO); SENÃO SE (posição = 1) ENTÃO RETORNE(retiraDoInício(aLista)); anterior <- aLista->dados; REPITA (posição - 2) VEZES anterior <- anterior->próximo; eliminar <- anterior->próximo; volta <- eliminar->info; anterior->próximo <- eliminar->próximo; aLista->tamanho <- aLista->tamanho - 1; LIBERE(eliminar); RETORNE(volta); FIM SE fim;

54 Algoritmo RetiraDaPosição
TipoInfo* FUNÇÃO retiraDaPosição(tLista *aLista, inteiro posição) //Elimina o elemento da posição de uma lista. //Retorna a informação do elemento eliminado ou NULO. variáveis tElemento *anterior, *eliminar; //Variável auxiliar para elemento. TipoInfo *volta; //Variável auxiliar para o dado retornado. início SE (posição > aLista->tamanho) ENTÃO RETORNE(NULO); SENÃO SE (posição = 1) ENTÃO RETORNE(retiraDoInício(aLista)); anterior <- aLista->dados; REPITA (posição - 2) VEZES anterior <- anterior->próximo; eliminar <- anterior->próximo; volta <- eliminar->info; anterior->próximo <- eliminar->próximo; aLista->tamanho <- aLista->tamanho - 1; LIBERE(eliminar); RETORNE(volta); FIM SE fim;

55 Modelagem do Tipo Info Para inserção em ordem e para achar um elemento determinado, necessitamos da capacidade de comparar informações associadas aos elementos; estas operações de comparação fazem parte do TAD TipoInfo e não da lista; devem ser implementadas como tal. Operações: testar AS INFORMAÇÕES: Igual(dado1, dado2) Maior(dado1, dado2) Menor(dado1, dado2)

56 Algoritmo AdicionaEmOrdem
Procedimento: necessitamos de uma função para comparar os dados (maior); procuramos pela posição onde inserir comparando dados; chamamos adicionaNaPosição(). Parâmetros: o dado a ser inserido; a Lista.

57 Algoritmo AdicionaEmOrdem
Inteiro FUNÇÃO adicionaEmOrdem(tLista *aLista, TipoInfo dado) variáveis tElemento *atual; //Variável auxiliar para caminhar. inteiro posição; início SE (listaVazia(aLista)) ENTÃO RETORNE(adicionaNoInício(aLista, dado)); SENÃO atual <- aLista->dados; posição <- 1; ENQUANTO (atual->próximo ~= NULO E maior(dado, atual->info)) FAÇA //Encontrar posição para inserir. atual <- atual->próximo; posição <- posição + 1; FIM ENQUANTO SE maior(dado, atual->info) ENTÃO //Parou porque acabou a lista. RETORNE(adicionaNaPosição(aLista, dado, posição + 1)); RETORNE(adicionaNaPosição(aLista, dado, posição)); FIM SE fim;

58 Algoritmos Restantes Por conta do aluno: Adiciona(lista, dado)
Retira(lista) RetiraEspecífico(lista, dado) Operações - inicializar ou limpar: DestróiLista(lista)

59 Algoritmo DestróiLista
FUNÇÃO destróiLista(tLista *aLista) variáveis tElemento *atual, *anterior; //Variável auxiliar para caminhar. início SE (listaVazia(aLista)) ENTÃO LIBERE(aLista); SENÃO atual <- aLista->dados; ENQUANTO (atual ~= NULO) FAÇA //Eliminar até o fim. anterior <- atual; //Vou para o próximo mesmo que seja nulo. atual <- atual->próximo; //Liberar primeiro a Info. LIBERE(anterior->info); //Liberar o elemento que acabei de visitar. LIBERE(anterior); FIM ENQUANTO FIM SE fim;


Carregar ppt "INE5408 Estruturas de Dados"

Apresentações semelhantes


Anúncios Google