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

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

Listas Lineares.

Apresentações semelhantes


Apresentação em tema: "Listas Lineares."— Transcrição da apresentação:

1 Listas Lineares

2 Introdução Uma lista é um depósito de dados usado para organizar informações. Nós usamos listas para quase tudo em nosso dia-a-dia: uma lista de compras para o supermercado, uma lista para os convidados de uma festa, uma lista de espera em uma companhia aérea, uma lista com arquivos para serem impressos, etc. As listas classificam-se em dois tipos: listas lineares e listas não-lineares. Uma lista linear é uma coleção de itens, também chamados nós, onde cada nó tem um único sucessor (desde que ele não seja o último). Assim, em uma lista linear existe o primeiro nó, o segundo nó, o terceiro nó e assim por diante. Uma lista não-linear é também uma coleção de nós só que, diferente das listas lineares, cada nó pode ter vários sucessores. Um exemplo de listas não-lineares são as árvores que serão apresentadas mais adiante.

3 Introdução Uma lista linear é dita ser ordenada se os nós estão ordenados de acordo com o valor de determinado campo denominado chave. A depender da maneira como uma lista linear é alocada ela pode ser seqüencial ou encadeada. Uma lista é seqüencial se cada um de seus elementos estão alocados em posições contíguas de memória, ao passo que na lista encadeada o armazenamento de seus elementos não atendem à contigüidade de seus elementos. As operações mais comuns em uma lista linear são: busca, inclusão e remoção.

4 Object vetor[ ] = new Object[5];
Lista linear Como foi dito acima, uma lista é seqüencial se, para cada nó da lista, seu sucessor está armazenado na posição seguinte de memória, como mostrado na seguinte figura: Na figura acima, se cada nó ocupa C posições de memória e se o primeiro nó está alocado na posição L, o segundo nó será alocado na posição L+C, o terceiro na posição L+2C e assim por diante. Uma das formas de se implementar uma lista seqüencial é através do uso de arrays, como mostrado abaixo: Object vetor[ ] = new Object[5];

5 Lista linear Os nós da lista podem conter qualquer tipo de informação sendo que normalmente cada nó contém um conjunto de várias informações onde uma destas informações, usada para diferenciar um nó dos demais, é chamada de chave e as demais são chamadas de dados satélite. Para efeito de simplicidade inicialmente iremos considerar em nossos exemplos que a classe lista irá manipular um vetor de inteiros. Para criar um Tipo Abstrato de Dados lista é necessário definir um conjunto de operações sobre os objetos do tipo Lista. O conjunto de operações efetivamente depende de cada aplicação, não existindo um conjunto que seja adequado a todas as aplicações.

6 Lista linear - operações
Um conjunto de operações necessário a maior parte das operações seria: Criar uma lista linear vazia Inserção de nó em lista não ordenada Pesquisa sequencial Pesquisa binária Inserção de nó em lista ordenada Remoção de nó em lista não ordenada Remoção de nó em lista ordenada Remover o i-ésimo item da lista (exercicio) Inserir um ítem na i-ésima posição (exercicio)

7 Inserção em lista não ordenada e pesquisa sequencial
Inserção de nó em lista não ordenada Uma vez que a lista não está ordenada qualquer elemento inserido será colocado no fim da lista. Implementar. Pesquisa sequencial A busca seqüencial é feita percorrendo-se a lista seqüencialmente a partir do primeiro nó. Pode-se demonstrar que, em média, teremos de percorrê-la até a sua metade para encontrar um determinado item. O método deve receber a chave procurada como argumento e retornar o índice da posição onde a chave foi encontrada. Caso ela não seja encontrada deve ser retornado o valor -1. Pode ser aplicada em qualquer tipo de lista. Analisando o algoritmo de busca seqüencial chegamos à conclusão de que no pior caso teremos de fazer N comparações ao passo que na média necessitamos de N/2 comparações. Concluímos então que esse algoritmo é de ordem O(N).

8 Pesquisa binária Busca binária
Caso a lista esteja ordenada, esta busca vai prover uma melhoria considerável no algoritmo de busca. O modelo desse algoritmo é bastante utilizado no nosso dia-a-dia quando desejamos, por exemplo, consultar um nome na lista telefônica. Dado um nome, você irá abrir o catálogo telefônico no início, no meio ou no fim a depender da primeira letra do nome. Se você tiver sorte, o nome procurado estará na página aberta. Caso contrário você irá continuar a procura nas páginas anteriores ou nas páginas posteriores a depender da letra do primeiro nome que se encontra na página aberta. Esse processo será repetido até que você encontre o nome desejado.

9 medio = (int) (inicio + fim) /2;
Pesquisa binária A idéia apresentada acima se aplica também para procurar um valor em uma lista ordenada. Inicialmente iremos para o meio da lista e verificamos se o valor procurado se encontra nessa posição. Se ele não estiver no meio da lista podemos concluir que ele só pode se encontrar ou na primeira metade ou na segunda metade da lista. Na metade onde o valor deverá estar, verificamos novamente se ele se encontra no seu meio. Se não estiver repetimos o processo até que o valor seja encontrado ou então para concluir que ele não se encontra na lista. Os seguintes passos descrevem o algoritmo. Vamos admitir inicialmente que o início da lista corresponde ao primeiro índice, isto é Inicio = 0, e que o final da lista corresponde ao último índice, ou seja Fim = N -1. Iremos calcular o índice correspondente ao ponto médio da lista medio = (int) (inicio + fim) /2; Comparamos então a chave com o valor que se encontra no meio da lista. Três possibilidades podem acontecer:

10 Pesquisa Binária A chave pode ser igual ao valor que está no meio da lista, assim o resultado da busca vai ser o índice do meio: if (chave == vetor[meio]) return meio A chave procurada é menor que o valor que se encontra no meio da lista, assim iremos continuar a busca na primeira metade da lista passando o valor de fim para meio-1. if (chave < vetor[meio]) fim = meio-1;

11 if (chave > vetor[meio]) inicio = meio+1;
Pesquisa binária A chave procurada é maior que o valor que se encontra no meio da lista, assim iremos continuar a busca na segunda metade da lista passando o valor de início para meio + 1. if (chave > vetor[meio]) inicio = meio+1; O algoritmo irá reduzindo sucessivamente os limites de procura na lista até chegar ao valor procurado. Eventualmente a chave pode não existir na lista, neste caso o índice retornado será -1. Exemplo: Considere a seguinte lista onde iremos procurar a posição onde se encontra a chave 33. Vetor = -7, 3, 5, 8, 12, 16, 23, 33, 55 Note que o algoritmo precisou fazer 3 comparações para encontrar o valor desejado. Se a busca tivesse sido feita usando a busca seqüencial seriam necessárias 8 comparações.

12 Análise do algoritmo de Pesquisa binária
Analisando o algoritmo da busca binária, pode-se concluir que o número máximo de comparações é aproximadamente Log2N, sendo portanto de ordem O(Log2N). Para sentir como a busca binária é bem mais rápida que a busca seqüencial, considere uma lista com nós. Enquanto que na busca seqüencial necessitaria, em média, 5000 comparações, na busca binária precisaríamos de no máximo 14 comparações.

13 Algoritmos de remoção Remoção de um nó em uma lista não ordenada:
Uma vez que a lista não é ordenada não temos que nos preocupar com isto. Para fazer a remoção de um ítem podemos simplesmente copiar o último ítem nesta posição e diminuir a lista de um elemento. O método será do tipo boolean e receberá como argumento a chave a ser procurada. Irá procurar na lista a posição do nó que será removido. Se a chave procurada não existir, o método retorna False, caso contrário, retorna True

14 Algoritmos de remoção Remoção de um nó em uma lista ordenada:
Como foi dito acima, no caso da lista ser ordenada, temos de garantir que, após a remoção do nó, a lista resultante permaneça ordenada. Isto pode ser conseguido da seguinte maneira: seja I a posição do nó que será removido; então todos os nós a partir da posição I+1 até o final da lista serão deslocados uma posição para a esquerda para ocupar a posição do nó removido, como ilustrado abaixo:

15 Análise dos algoritmos de remoção
Para a lista não ordenada O maior tempo gasto está na busca seqüencial do nó que será removido. Como a ordem da busca é O(N), o algoritmo para inserir um nó em uma lista ordenada também terá essa ordem. Para a lista ordenada Ao contrário da lista não ordenada, o maior tempo gasto está em deslocar os nós para colocar o novo nó na posição correta, cuja ordem é O(N). Assim essa ordem também será a ordem do algoritmo para inserir um nó em uma lista ordenada.

16 Inserção em lista ordenada
Como já falamos no início da aula, a inserção de um elemento em uma lista não ordenada é muito simples pois basta colocá-lo no final da lista. Em uma lista ordenada temos de incluir o elemento de forma que a lista continue ordenada. A inserção em uma lista ordenada será feita procurando-se a posição onde o novo dado deverá ficar. A seguir todos os itens situados à direita da posição encontrada serão deslocados para a direita para permitir a inserção na posição correta, como ilustrado abaixo ao ser inserida a chave 5.


Carregar ppt "Listas Lineares."

Apresentações semelhantes


Anúncios Google