3.4 Representação física: alocação encadeada (dinâmica) As posições de memória são alocadas (ou desalocadas) na medida em que são necessárias (ou dispensadas). Os nós de uma lista encontram-se aleatoriamente dispostos na memória e são interligados por ponteiros, que indicam a posição de memória (endereço) do próximo elemento. O último nó contém em seu link o endereço nulo (λ), indicando que não há nós sucessores. Ptlista Nó 1 Nó 2 Nó 3 Nó 4 λ Ptlista - variável ponteiro externa que indica o início da lista. Formato de um nó: Informação link Link endereço do próximo nó. 3.4.1 LED: Lista de Espaço Disponível heap - área de memória onde, dinamicamente, serão criadas as estruturas de trabalho. LED - Lista especial que contém as posições de memória ainda não utilizadas ou dispensadas após utilização. LED e estruturas compartilham a memória disponível. Gerenciamento da LED: reserva e posterior liberação de memória. Duas formas: pelo usuário, através de dimensionamento de vetor(es) simulando a memória total disponível. O endereço do nó corresponde ao índice de uma posição do vetor.
LED (inicio) vago (topo da estrutura) informação próx 2 3 4 pt índice do nó disponível λ Busca de um elemento na LED Procedimento se vago < > λ então pt vago vago LED[vago].prox senão overflow Devolução de um nó à LED Procedimento des LED[pt].prox vago vago pt pelas linguagens de programação, através dos módulos de gerência de memória disponível ao usuário. Em Pascal, as rotinas new(pt) e dispose(pt) executam essas tarefas. Notação utilizada nos algoritmos: ponteiro. campo 3.4.2 Lista simplesmente encadeada 3.4.2.1 Listas lineares em geral
Estrutura de armazenamento: criação de um nó especial (nó cabeça) sem informações relacionadas à tabela propriamente dita, nunca removido, que passa a ser o nó indicado pelo ponteiro de início de lista. Lista vazia: (nó cabeça) Lista não vazia: Nó 1 Nó 2 Nó n λ Formato de um nó: Informação info link prox 3.4.2.1.1 Percurso (impressão da lista apontada por ) // ponteiro para o primeiro nó // pont - ponteiro de percurso pont enquanto pont <> λ faça imprimir(pont. info) pont pont. prox 3.4.2.1.2 Busca em uma lista ordenada pont retorna apontando para o elemento procurado. Caso não seja encontrado pont aponta para λ. ant - retorna apontando para o elemento anterior ao procurado. Caso não seja encontrado, ant indica o elemento anterior ao último pesquisado. ptr ponteiro de percurso. x chave procurada. Procedimento busca_enc(x, ant, pont) ant ; pont λ; ptr. prox enquanto ptr <> λ faça se ptr. chave < x então ant ptr // atualiza ant e ptr
ptr ptr. prox senão se ptr. chave = x então pont ptr // chave encontrada ptr λ 3.4.2.1.3 Inserção de um nó (após o nó apontado por ant) Três fases: Comunicação com a LED Acesso ao campo de informação do nó Acerto da estrutura Ptlista ant λ pt busca_enc(x, ant, pont) se pont = λ então // elemento não existe pt. chave x; pt. prox ant. prox ant. prox pt // acertar estrutura senão Elemento já está na tabela 3.4.2.1.4 Remoção de um nó (apontado por pont na lista) Ptlista ant pont λ busca_enc(x, ant, pont)
se pont <> λ então // elemento existe ant. prox pont. prox // acertar estrutura valor_recuperado pont. info // utilizar nó desocupar(pont) // devolver nó senão Elemento não está na tabela 3.4.2.2 Pilha (sem nó cabeça) 3.4.2.2.1 Inserção na pilha pt. prox topo // acertar pilha topo pt 3.4.2.2.2 Remoção da pilha se topo <> λ então pt topo // acertar pilha topo topo. prox valor recuperado pt. info // utilizar nó des // devolver nó senão underflow 3.4.2.3 Fila Dois ponteiros: início aponta par o primeiro nó da lista fim - aponta para o último nó da lista Fila vazia: inicio = fim = λ 3.4.2.3.1 Inserção na fila pt. prox λ se fim < > λ então // acertar fila fim. prox pt
senão inicio pt fim pt 3.4.2.3.2 Remoção da fila se início < > λ então pt início // acertar fila início início. prox se início = λ então // fila ficou vazia fim λ valor recuperado pt. info // utilizar nó des // devolver nó senão underflow 3.4.3 Listas circulares simplesmente encadeadas (o último nó da lista aponta para o nó cabeça) Nó 1 Nó 2 Nó n 3.4.3.1 Busca numa circular encadeada ordenada Colocar a chave procurada no nó cabeça. O ponteiro pont tem o valor de se o elemento não é encontrado. Procedimento busca_cir(x, ant, pont) ant ;. chave x; pont. prox enquanto pont. chave < x faça ant pont; pont pont. prox se pont < > e pont. chave = x então Chave localizada senão Chave não localizada Exercício: Busca em listas circulares não ordenadas.
3.4.3.2 Inserção e Remoção (exercício) Para termos acesso ao nó anterior ao que estamos posicionados temos que usar um ponteiro rastreador (ant). E se quisermos ter acesso a todos os nós anteriores? 3.4.4 Listas duplamente encadeadas (dois links no nó: um aponta para o sucessor, outro para o antecessor) 3.4.4.1 Listas Lineares em geral Duas variáveis ponteiro externas: uma para indicar o nó mais à esquerda (PtrEsq) e outra para indicar o nó mais à direita (PtrDir). PtrEsq PtrDir λ Nó 1 Nó 2 Nó 3 Nó n λ Formato de um nó: ant info prox 3.4.4.2 Lista circular duplamente encadeada (com nó cabeça) Nó 1 Nó 2 Nó n 3.4.4.2.1 Busca em uma lista ordenada (a função retorna indicando o nó procurado ou, se este não for encontrado, o seu consecutivo) Função Busca_dup(x) ultimo. ant se x ultimo. chave então pont. prox enquanto pont. chave < x faça // ponteiro de percurso
pont pont. prox // percorre a lista Busca_dup pont senão Busca_dup 3.4.4.2.2 Inserção em lista circular duplamente encadeada pont pt pont Busca_dup(x) se pont = ou pont. chave < > x então anterior pont. ant // guarda endereço do anterior pt. chave x pt. ant anterior pt. prox pont anterior. prox pt // acertar lista pont. ant pt senão Elemento já se encontra na lista 3.4.4.2.3 Remoção de lista circular duplamente encadeada pont pont Busca_dup(x) se pont < > e pont. chave = x então anterior pont. ant // guarda endereço do anterior
posterior pont. prox anterior. prox posterior // acertar lista posterior. ant anterior valor_recuperado pont. info desocupar(pont) senão Elemento não se encontra na lista 3.4.4.3 Deque (Inserções e remoções restritas às extremidades) PtrEsq PtrDir λ Nó 1 Nó 2 Nó 3 Nó n λ Deque vazio: PtrEsq =PtrDir = λ 3.4.4.3.1 Inserção à esquerda pt. chave x pt. ant λ pt. prox PtrEsq se PtrEsq < > λ então PtrEsq. ant pt // acerta Deque senão // Deque estava vazio PtrDir pt // Inicializa PtrDir PtrEsq pt // Atualiza PtrEsq 3.4.4.3.2 Remoção à esquerda se PtrEsq < > λ então pont PtrEsq posterior PtrEsq. Prox se posterior < > λ então posterior. ant λ senão PtrDir = λ valor_recuperado pont. Info desocupar(pont) PtrEsq posterior senão Deque vazio // Deque não vazio // acertar lista // Deque ficou vazio // utilizar nó // devolver nó // Atualizar PtrEsq