Listas lineares Listas lineares Uma Lista Linear (LL) é uma seqüência de nodos São as estruturas de mais simples manipulação Lista linear a b c d Relação de ordem Linear - seqüencial e Estrutura dos nodos Estrutura interna é abstraída Pode ter uma complexidade arbitrária Enfatizado o conjunto de relações existente a b c d INFORMAÇÕES Número RG Nome Nasc. Cargo z
Estrutura dos nodos Definição matemática Uma lista linear é uma coleção de n 0 nodos x[1], x[2],..., x[n], cujas propriedades estruturais relevantes envolvem apenas as posições relativas lineares dos nodos: n > 0 : x[1] é o primeiro nodo x[n] é o último nodo 1 < k < n : x[k] é precedido por x[k-1] e sucedido por x[k+1] n = 0 lista vazia Lista linear : seqüência de 0 ou mais nodos do mesmo tipo Exemplos de aplicações com listas notas de alunos cadastro de funcionários de uma empresa itens em estoque em uma empresa dias da semana vagões de um trem letras de uma palavra pessoas esperando ônibus cartas de baralho precipitações pluviométricas em um mês / dia Operações sobre listas lineares Criação de uma lista Destruição de uma lista Inserção de um nodo na i-ésima posição Exclusão do i-ésimo nodo Acesso ao i-ésimo nodo Alteração do i-ésimo nodo Combinação de duas ou mais listas Classificação da lista Cópia da lista Determinar cardinalidade da lista Localizar nodo através de info Mais comuns devem ser eficientes!
Representação física de uma lista linear Representação física das relações existentes entre os nodos e não aquelas internas a eles Contigüidade física Encadeamento Listas lineares Contigüidade física Algoritmos para implementar operações sobre LL????????? Tipo de dados para armazenar os elementos da lista Componentes para controle da estrutura lista inicializa(): Cria lista insere(): Insere um nodo na k-ésima posição da lista remove(): Remove o k-ésimo nodo da lista consulta(): Consulta o k-ésimo nodo da lista altera(): Substitui o nodo na k-ésima posição da lista por outro Destroi(): destrói a lista
????????? Lista linear - Contigüidade física Seqüencialidade da memória Endereços fisicamente adjacentes nodos logicamente adjacentes Ex: suporte da lista é um arranjo de 1 dimensão - todos elementos do arranjo de tipo igual - cada elemento 1 nodo - tipo do elemento - tipo do nodo declaração TipoLista = arranjo [1..n] de TipoNodo; var LL : tipolista; Lista linear - Contigüidade física Lista linear Lista = arranjo [1..n] de TipoNodo; var minhalista : Lista; L2 L3 L4 L5 L6 Ln????? L L 1 2 3 4 5 6 n Arranjo
Lista linear - Contigüidade física Lista linear - Contigüidade física e final da lista diferentes do início e final do arranjo Um mesmo arranjo pode ser utilizado para mais de uma lista linear Variáveis para identificar e Final da lista LL 1 2 3 4 5 k-1 k L2 L3 Lm-1 Lm Ini IniL2 L2????? Operações sobre listas lineares em contigüidade física criar lista inserir nodo remover nodo alterar nodo... Algoritmos
inicializa(???): Cria lista insere(???): Insere um nodo na k-ésima posição da lista consulta(???): Consulta o k-ésimo nodo da lista inicializa(???): Cria lista insere(???): Insere um nodo na k-ésima posição da lista consulta(???): Consulta o k-ésimo nodo da lista Criação de uma lista linear implementada sobre um arranjo declarar o arranjo inicializar variáveis que guardam início e final da lista Arranjo X [ 1.. N ] 1 2 3 4 5 Ex: Lista de informações de produtos de uma empresa TipoNodo = registro Nome: string; Código: inteiro; Preço: real fim registro; TipoLista = arranjo [1.. N] de TipoNodo Ini = = 0 Lista vazia Ini = = -1 0 1 2 3 M Proc InicializarLLArranjo (var IniLista,Lista: inteiro); início IniLista := 0 ; Lista := 0 ; fim InicializarLLArranjo;
insere(???): Insere um nodo na k-ésima posição da lista consulta(???): Consulta o k-ésimo nodo da lista insere(???): Insere um nodo na k-ésima posição da lista consulta(???): Consulta o k-ésimo nodo da lista Acessar o k-ésimo nodo de uma lista Procedimento para consultar o k-ésimo nodo 1 2 3 4 5 k-1 k 1 2 3 4 5 k-1 k L2 L3 Lm-1 Lm L2 L3 Lm-1 Lm K = 3 K = 3 Consulta a informações do nodo Acessar para Alteração de algum campo de informação do nodo Recebe k (ordem do nodo na lista) nome do arranjo LL índices Ini, de controle da lista Devolve InfoNodo contido no campo de informação do nodo Sucesso informando se teve sucesso no acesso Testar: se o k-ésimo nodo faz parte da lista pode ser o primeiro (índice Ini)... até o último (índice - Ini + 1) se a lista não está vazia
insere(???): Insere um nodo na k-ésima posição da lista // devolve a posição (o índice no arranjo) do nodo para o qual o campo valor é igual ao valor buscado (val) Procedimento para consultar o k-ésimo nodo Proc ConsultarK (LL: TipoLista; K, Ini, : inteiro; var Sucesso: lógico; var InfoNodo: TipoNodo); início se K < 0 { antes do primeiro nodo da lista } ou K > - Ini + 1 { depois do último nodo da lista } ou Ini = 0 { lista vazia } então Sucesso := Falso senão início Infonodo := LL [ Ini + K - 1]; Sucesso := Verdadeiro fim fim ConsultarK; 1 2 3 4 5 k-1 k L2 L3 Lm-1 Lm K = 3 insere(???): Insere um nodo na k-ésima posição da lista // devolve a posição (o índice no arranjo) do nodo para o qual o campo valor é igual ao valor buscado (val) Inserir novo nodo em LL - contigüidade física No início No final No meio A A A 11 12 13 14 15 16 17 18 19 20 21 22 23 11 12 13 14 15 16 17 18 19 20 21 22 23 11 12 13 14 15 16 17 18 19 20 21 22 23 Observar o preenchimento das estruturas...
1 2 3 4 5 6 7 L2 L3 L4 L5 Inserir como primeiro nodo K = 3 L2 L3 L4 L5 L6 K = 1 L2 L3 L4 L5 L6 Ex: 33 70 70 40 40 20 20 90 90 80 80 K = 3 Inserir como último nodo Inserir no meio da lista linear L2 L3 L4 L5 L6 L2 L3 L4 L5 L6 K = 6 K = 3
Ex: Inserir no meio da lista linear 77 33 44 55 99 44 88 99 88 5 1 2 3 4 k-1 k Ini L2 L3 Lm-1 Lm K = 3 Posição do novo nodo na lista Proc InserirPosK (var LL: TipoLista; N: inteiro; K: inteiro ; InfoNodo: TipoNodo; var Ini, : inteiro; var Sucesso: lógico K = 3 Valor a ser inserido Se obteve sucesso Analisar: lista vazia (Ini e = 0), só se for K = 1 (primeiro da lista) Ini = 1 (início do arranjo) e = N (final do arranjo) - não tem mais espaço para inserir (insucesso) pode inserir como primeiro, no meio, ou logo após o último ( K ) se = N e tem espaço antes, deslocar nodos para frente function insere (var x: Lista; k: integer ; val: Info; var ini, fim: integer): boolean; // insere um nodo em uma lista, na posição K // devolve a posição (o índice no arranjo) do nodo para o qual o campo valor é igual ao valor buscado (val) Proc InserirPosK (var LL: TipoLista; N: inteiro; K: inteiro; Inserção InfoNodo: de TipoNodo; novo nodo var Ini, na : k-ésima inteiro; var Sucesso: posição lógico); var Ind : inteiro; início se (Ini = 1 e = N) { não tem mais espaço no arranjo } ou (K > - Ini + 2) { posição de inserção inválida } ou (K < 0) { idem } ou (Ini = 0 e K 1) { lista vazia, só pode ser primeiro nodo } então Sucesso := falso { inserção não pode ser realizada } senão início { vai ser realizada a inserção } se Ini = 0 { lista estava vazia } então Ini := := 1 { atualiza Ini e } senão se N { tem espaço no final } então início para Ind de incr -1 até Ini+K-1 faça LL[Ind+1] := := LL[I]; := +1; fim senão início { deslocar nodos para baixo } para Ind de Ini incr 1 até Ini+K-2 faça LL[Ind-1] := LL[Ind]; Ini:=Ini - 1; fim; LL [Ini+K-1] := InfoNodo; { insere nodo com Infonodo na posição K } Sucesso := verdadeiro { inserção realizada com sucesso }
Otimizar: deslocar nodos da metade para baixo se a inserção for na primeira metade da lista, e da metade para cima se for na segunda metade desde que haja espaço no lado considerado 70 K 3 K > 3 40 20 90 80 9 10 Proc Inserção InserirPosKOt de novo (var nodo LL: TipoLista; na k-ésima N: inteiro; posição K: inteiro; da LL InfoNodo: TipoNodo; var Ini, : inteiro; var Sucesso: lógico) var Ind : inteiro; início se (Ini = 1 e = N) ou (K > - Ini + 2) ou (K < 0) ou (Ini = 0 e K 1) então Sucesso := falso { inserção não pode ser realizada } senão início { vai ser realizada a inserção } se Ini = 0 { lista estava vazia } então Ini := := N/2 { insere no meio, para otimização } senão se Ini=1 ou (( N) e (K > ( Ini+1)/2)) então início { deslocar nodos para cima } para Ind de incr -1 até Ini+K-1 faça LL[Ind+1] := LL[Ind]; := +1; fim senão início { deslocar nodos para baixo } para Ind de Ini incr 1 até Ini+K-2 faça LL[Ind-1] := LL[Ind]; Ini:=Ini - 1; fim; LL[Ini+K-1] := InfoNodo; { insere nodo com InfoNodo } Sucesso := verdadeiro; { inserção realizada com sucesso } fim; fim InserirPosKOt; function insere (var x: Lista; k: integer ; val: Info; var ini, fim: integer): boolean; // insere um nodo em uma lista, na posição K // devolve a posição (o índice no arranjo) do nodo para o qual o campo valor é igual ao valor buscado (val) Remoção do k-ésimo nodo de uma LL 1 2 3 4 5 6 7 Remover K = 3 L2 L3 L4 L5 1 2 3 4 5 6 7 L2 L3 L4
function insere (var x: Lista; k: integer ; val: Info; var ini, fim: integer): boolean; // insere um nodo em uma lista, na posição K function removek(var x: Lista; k: integer; var ini, fim: integer): boolean; // remove um nodo da posição K // devolve a posição (o índice no arranjo) do nodo para o qual o campo valor é igual ao valor buscado (val) Remoção do k-ésimo nodo de uma LL Proc RemoverK (var LL: TipoLista; K: inteiro; var Ini, : inteiro; var Sucesso: lógico); var Ind: inteiro; início se K < 0 ou K > - Ini + 1 { posição solicitada fora da lista } então Sucesso := falso senão início { vai realizar a remoção } para Ind de Ini+K-1 incr 1 até -1 faça LL [Ind] := LL [Ind+1]; { desloca o resto da lista } := - 1; { atualiza } se = Ini 1 { lista ficou vazia } então Ini := := 0; Sucesso := Verdadeiro fim fim RemoverK; Otimização da remoção do k-ésimo nodo Deslocar nodos da metade para baixo se o nodo a ser removido estiver na primeira metade da lista, e da metade para cima se estiver na segunda metade desde que haja espaço no lado considerado K 3 K > 3 Remover K=2 70 40 20 90 80 23 70 20 90 80 23 9 10 9 10 Obtenção do valor e remoção do k-ésimo nodo de uma LL X1 X2 X3 Ini X4 L2 Proc ObterERemover (var LL: TipoLista; K: inteiro; var Ini, : inteiro; var Sucesso: lógico; var InfoNodo: TipoNodo); var Ind: inteiro; se K < 0 ou K > - Ini + 1 { testa se ordem K está na lista} então Sucesso := Falso senão início InfoNodo := LL [Ini+K-1]; { obtém o valor } para Ind de Ini+K-1 incr 1 até -1 faça LL [Ind] := LL [Ind+1]; { desloca os seguintes } := - 1; { atualiza } se = Ini - 1 então Ini := := 0; { lista vazia } Sucesso := Verdadeiro fim ObterERemover X5 L3 k Xk Lm-1 Xk+1 Lm Xn-1 Xn
function insere (var x: Lista; k: integer ; val: Info; var ini, fim: integer): boolean; // insere um nodo em uma lista, na posição K function removek(var x: Lista; k: integer; var ini, fim: integer): boolean; // remove um nodo da posição K // devolve a posição (o índice no arranjo) do nodo para o qual o campo valor é igual ao valor buscado (val) function insere (var x: Lista; k: integer ; val: Info; var ini, fim: integer): boolean; // insere um nodo em uma lista, na posição K function removek(var x: Lista; k: integer; var ini, fim: integer): boolean; // remove um nodo da posição K function removeval(var x: Lista; val: info; var ini, fim: integer): boolean; // remove um nodo cujo valor é val // devolve a posição (o índice no arranjo) do nodo para o qual o campo valor é igual ao valor buscado (val)