330 likes | 490 Views
Listas Ligadas. Estruturas de Dados e Algoritmos. Listas Ligadas. Desvantagens do armazenamento seqüencial para representar pilhas e filas: Subdimensionamento ou superdimensionamento da memória devido a alocação fixa de uma certa quantidade de memória antes da execução do programa
E N D
Listas Ligadas Estruturas de Dados e Algoritmos Fábio Lopes Caversan
Listas Ligadas • Desvantagens do armazenamento seqüencial para representar pilhas e filas: • Subdimensionamento ou superdimensionamento da memória devido a alocação fixa de uma certa quantidade de memória antes da execução do programa • Possibilidade de overflow Fábio Lopes Caversan
Compartilhando a memória disponível • Suponha uma implementação seqüencial de pilhas • Stack x,y,z; • Suponha que sejam inicializadas, de forma estática, com 50 elementos • x,y,z terão, durante a utilização, respectivamente, no máximo, 20, 10 e 70 elementos Fábio Lopes Caversan
Fazendo cálculos • 100 células seriam necessárias • Porém, na inicialização, deve-se usar o tamanho 70 para não ocorrer um overflow • Então, temos 3* 70 = 210,quando somente 100 serão utilizadas • Que tal evitar esse desperdício através de um gerenciador de memória? • Ele controlaria quem recebe mais ou menos células de memória Fábio Lopes Caversan
Agrupando as células livres num banco de memória livre Banco de memória Variáveis x y z nada nada nada Fábio Lopes Caversan
Operação Banco de memória x y z x.Push(a) (nada) (nada) y.Push(b) (nada) y.Push(c) (nada) x.Push(d) (nada) z.Push(e) (nada) Fábio Lopes Caversan
Operação Banco de memória x y z z.Push(f) (nada) y.Pop() z.Pop() (nada) x.Pop() (nada) z.Push(g) Fábio Lopes Caversan
Considerações importantes • A ordem das células de memória disponíveis no banco, no decorrer da execução da aplicação, muda substancialmente • O importante é manter um controle sobre a ordem lógica das células de memória e não, necessariamente, sobre a ordem física Fábio Lopes Caversan
Lista Ligada (Encadeada) Linear • Cada item na lista é um nó • Todo nó contem dois campos: o de informação e do endereço seguinte • Campo de informação: armazena o real elemento da lista • Campo de endereço: endereço do próximo nó na lista. É um ponteiro! Fábio Lopes Caversan
Endereço do próximo nó Informação nulo Algumas representações do nó ... Fábio Lopes Caversan
Continuando . . . • A lista ligada inteira é acessada a partir de um ponteiro externo que aponta para o primeiro nó da lista • Um ponteiro externo não está incluindo dentro de um nó. É acessado por referência a uma variável • O campo do próximo endereço do último nó da lista contém um valor especial: null • O ponteiro nulo (null) marca o final da lista • Uma lista sem nós é uma lista vazia ou nula • Nesse caso, o ponteiro externo para a lista é nulo • Uma lista pode ser inicializada por uma operação do tipo list = null (sendo list o ponteiro externo) Fábio Lopes Caversan
Pilha Heap Variáveis Globais Código do Programa Revisando o mapa conceitual de um programa na memória Endereços de retorno de funções, variáveis locais Alocação dinâmica: listas encadeadas Fábio Lopes Caversan
Ao “fotografar” a memória do computador Área Livre (Heap) Programa LIST Ponteiro externo que aponta para o primeiro nó da lista ligada. Cuidado com sua manipulação! Fábio Lopes Caversan
N1 Nnnull N2 N3 L . . . • Dois endereços merecem atenção especial: • O endereço L do nó inicial que permite identificar em que parte da memória inicia-se a lista • O endereço NULL que vem após o nó final. É onde termina a lista • Sempre lembrando, cada nó i é composto de duas partes: • Info: área onde é armazenado o i-ésimo elemento da lista • Next: área onde é armazenado o “endereço” do nó N i + 1 Fábio Lopes Caversan
Declarando uma classe Nó para uma lista ligada Um dos atributos da classe precisa ser um ponteiro para uma estrutura do mesmo tipo public class Node { private object info; private Node next; ... }; Fábio Lopes Caversan
Permitindo o acesso aos atributos • De acordo com a linguagem, pode ser necessária a escrita de métodos para ler e escrever nos atributos, garantindo o encapsulamento. • Nas linguagens que possuem propriedades, isso pode ser feito com os comandos get e set. • Cada vez que atribuímos um valor para a propriedade, o set é chamado. Cada vez que lemos um valor da propriedade, o get é chamado. Fábio Lopes Caversan
public class Node { private object info; private Node next; public object Info { get {return info;} set {info = value;} } public Node Next { get {return next;} set {next = value;} } ... }; Fábio Lopes Caversan
Incluindo um elemento no início da lista info next info next info next list 5 8 nulo 3 p info next info next info next list 5 3 8 nulo 6 p info next info next info next 5 3 8 nulo list Fábio Lopes Caversan
5 5 5 3 3 3 8 nulo 8 nulo 8 nulo 6 p list p 6 list 6 list Fábio Lopes Caversan
Os passos anteriores são expressos pelo seguinte algoritmo Node p = new Node(); p.Info = x; p.Next = list; list = p; Fábio Lopes Caversan
info next info next info next 7 list 5 9 nulo P 7 9 nulo 5 list 7 9 nulo X=7 P 5 list 7 P 5 9 nulo list P 7 5 9 nulo list 9 nulo 5 Removendo um nó do início de uma lista list Fábio Lopes Caversan
Os passos anteriores para remover um nó são expressos pelo seguinte algoritmo Node p = list; list = p.Next; x = p.Info; Fábio Lopes Caversan
Implementação ligada de Pilhas • Incluir um elemento no início de uma lista ligada é semelhante à inclusão numa pilha • O 1º nó da lista representa o topo da pilha • Vantagem: todas as pilhas ou filas usadas por um programa podem compartilhar a mesma lista de nós disponíveis, desde que não ultrapassam a quantidade total de nós disponíveis Fábio Lopes Caversan
7 nulo 5 3 8 7 nulo 5 3 8 6 Uma pilha usando lista ligada stack stack Fábio Lopes Caversan
Como o 1º nó da lista é o topo da lista A implementação de Push (x) poderia ficar: Node p = new Node( ); p.Info = x; p.Next = stack; stack = p; Fábio Lopes Caversan
A implementação de x = pop (s) poderia ficar : if (Empty ()) // Exception, mensagem, etc... else { Node p = stack; stack = p.Next; x = p.Info; p = null; return x; } Fábio Lopes Caversan
7 4 3 1 6 nulo 9 9 7 1 3 nulo 4 Uma fila usando lista ligada final início final início Fábio Lopes Caversan
Algoritmo para x = q.Remove () if (Empty()) // Exceção, mensagem, etc... Node p = front; x = p.Info; front = p.Next; if (front = = null) rear = null; p = null; return ( x ); A fila q consiste numa fila e dois ponteiros: front e rear. As operações q.Empty() e x=q.Remove() são análogas a s.Empty(s) e x=s.Pop(s), basta substituir front por stack. Muita atenção ao remover o último elemento da fila: rearfica também nulo porque se a fila está vazia front e reardevem ser nulos Fábio Lopes Caversan
Algoritmo para q.Insert (x) Node p = new Node(); p.Info = x; p.Next = null; if (rear = = null ) front = p; else rear.Next = p; rear = p; Fábio Lopes Caversan
Desvantagens de pilhas e filas como listas ligadas? • Mais armazenamento do que o vetor: Info e Next • Mas o espaço de armazenamento não é o dobro. Depois, pode-se compactar as informações • Cada inclusão/exclusão corresponde a uma inclusão/exclusão na lista de nós disponíveis • Grande vantagem: compartilhamento de nós, desde que não ultrapasse o número de nós disponíveis Fábio Lopes Caversan
Listas ligadas como estruturas de dados • São importantes não só para implementar pilhas e filas, mas como estruturas de dados • Acessa-se um item percorrendo-se a lista a partir do início • Um vetor permite o acesso direto ao enésimo item com uma única operação • Já uma lista exige n operações e é necessário percorrer cada um dos primeiros n-1 elementos antes do enésimo • Vantagem da lista: aparece na inserção ou remoção de um elemento porque não é necessário nenhuma movimentação dos n elementos Fábio Lopes Caversan
x0 x1 x2 x3 x4 x5 Inserção de um novo elemento num vetor x0 x1 x2 x3 x4 x5 x0 x1 x2 x x3 x4 x5 x6 Fábio Lopes Caversan
X3 X1 X4 nulo X2 X3 X0 X1 X0 X4 nulo X X2 Já numa lista o trabalho de inserção independe do seu tamanho n list n list InsertAfter (n,x) Node p = new Node() p.Info = x; p.Next = n.Next; n.Next = p DeleteAfter(n) Node p = n.Next; x = p.Info; n.Next = p.Next; p = null; Fábio Lopes Caversan