• Nenhum resultado encontrado

9 - ListasEncadeadasParte1

N/A
N/A
Protected

Academic year: 2021

Share "9 - ListasEncadeadasParte1"

Copied!
11
0
0

Texto

(1)

Universidade Federal de Itajubá – Campus Itabira

Engenharia da Computação

ECO010 - Estruturas de Dados Profa. Claudia A. Izeki

Listas Encadeadas Dinâmicas

Uma lista linear agrupa informações referentes a um conjunto de elementos que, de alguma forma, se relacionam entre si. Uma lista linear é um conjunto de n >= 0 elementos ou nós: L[1], L[2], ..., L[n] tais que suas propriedades estruturais são:

Se n é igual a 0, a lista está vazia;

Se n > 0, L[1] é o primeiro elemento da lista;

L[n] é o último elemento da lista;

Para 1 < k <= n, o nó L[k] é precedido por L[k-1] e seguido pelo elemento L[k+1].

Em outras palavras, a característica fundamental de uma lista linear é o sentido de ordem unidimensional dos elementos que a compõem. Pode-se dizer com precisão onde o conjunto de elementos se inicia e onde termina, sem possibilidade de dúvida.

Do ponto de vista de organização da memória, uma lista pode ser sequencial (sucessor lógico de um elemento ocupa posição física consecutiva na memória) ou encadeada (elementos logicamente consecutivos não implicam endereços consecutivos na memória). Já em relação à alocação, uma lista linear pode ser estática (a reserva de memória se dá em tempo de compilação) ou dinâmica (a reserva de memória se dá em tempo de execução).

Até agora vimos listas estáticas sequenciais e encadeadas, além de listas dinâmicas sequenciais. Nesta aula veremos as listas dinâmicas encadeadas.

A representação das listas lineares dinâmicas encadeadas é realizada por encadeamento dinâmico de nós. Ao invés de manter os elementos agrupados numa área contínua, ou seja, ocupando posições consecutivas na memória, na alocação encadeada os elementos ocupam quaisquer células, não necessariamente consecutivas e, para manter a relação de ordem linear, juntamente com cada nó é armazenado o endereço do próximo nó da lista.

(2)

Desta forma, na alocação encadeada, os elementos estão armazenados em blocos de memória denominados nós, sendo que cada nó é composto por pelo menos dois campos: um para armazenar dados e outro para armazenar endereço.

Dois tipos de nós especiais devem ser destacados:

o nó que aponta para o primeiro elemento da lista, denominado comumente como inicio;

o nó NULO ou NULL que indica término de uma lista.

A alocação encadeada apresenta como maior vantagem a facilidade de inserir ou remover elementos do meio da lista. Como os elementos não precisam estar armazenados em posições consecutivas de memória, nenhum dado precisa ser movimentado, bastando atualizar o campo de ligação do elemento que precede aquele inserido ou removido. Na Figura 1 pode ser observado um exemplo de lista encadeada de nós que tem seu início indicado pelo nó início e seu término pelo nó nulo.

Quando os nós de uma lista encadeada possuem informação do próximo nó da lista, esta é chamada lista simplesmente encadeada. Já quando os nós possuem ponteiros para o próximo nó e para o seu anterior, a lista é chamada de duplamente encadeada. Neste roteiro, o foco são as listas simplesmente encadeadas.

Figura 1. Lista dinâmica encadeada de nós, também chamada de lista simplesmente encadeada.

(3)

A implementação de uma lista dinâmica encadeada caracteriza-se na forma de declarar o nó e a lista. Observe no quadro a seguir a declaração da lista encadeada utilizando struct e class.

Código C/C++ com struct Código c/C++ com class struct No { int info; No *proximo; }; class No { private: int info; No *proximo; public: // construtor // destrutor // getters e setters }; struct Lista { No *inicio; }; // inserção de um nó na lista // remoção de um nó na lista // demais métodos class Lista { private: No *inicio; public: // construtor // destrutor // inserção de um nó na lista // remoção de um nó da lista // demais métodos };

Deve-se notar que se trata de uma estrutura auto-referenciada, pois, além do campo que armazena a informação (no caso, um número inteiro), há um campo que é um ponteiro para uma próxima estrutura do mesmo tipo.

Pode-se operar sobre esta lista encadeada, inserindo-se nós no começo, no meio ou no final de uma lista.

(4)

Para inserir no início da lista, deve-se criar um novo nó, por exemplo, "9", e acrescentá-lo ao início da lista, conforme ilustrado na Figura 2.

Figura 2. Inserção de um novo nó "9" no início da lista encadeada.

Ao remover o elemento, por exemplo, "1", do início da lista, o início deve apontar para o próximo nó apontado por início, conforme ilustrado na Figura 3. Depois da última atribuição, já é seguro "destruir" o "1".

(5)

Ao inserir um nó "4" no final da lista, o último nó "7" deve apontar para o novo nó da lista, conforme ilustrado na Figura 4.

Figura 4. Inserção de um novo nó "4" no final da lista.

Ao remover o nó "7" do final da lista, o penúltimo nó "8" deve apontar para o nó apontado por "7" que é o nó nulo; assim o nó "7" pode ser destruído, conforme ilustrado na Figura 5.

(6)

2. Implementação de uma Lista Dinâmica Simplesmente Encadeada

Arquivo: NoLista.h Arquivo: Lista.h

#ifndef NOLISTA_H_INCLUDED #define NOLISTA_H_INCLUDED class No { private: int info; No *proximo; public: No(); ~No();

void setInfo(int _info);

void setProximo(No *_proximo); int getInfo();

No* getProximo(); };

// implementação dos métodos da classe #endif // NOLISTA_H_INCLUDED #ifndef LISTA_H_INCLUDED #define LISTA_H_INCLUDED #include "NoLista.h" #include<iostream> using namespace std; class Lista { private: No *inicio; public: Lista(); ~Lista(); void insere_inicio_lista(int info); void insere_final_lista(int info); void remove_inicio_lista(); void remove_final_lista(); void imprime_lista(); bool lista_vazia(); };

// implementação dos métodos da classe

#endif // LISTA_H_INCLUDED

Implementação dos métodos da classe No:

No::No() {

info = 0; proximo = 0; }

(7)

No::~No() {

if (proximo) delete proximo; proximo = 0; }

void No::setInfo(int _info) {

info = _info; }

void No::setProximo(No *_proximo) { proximo = _proximo; } int No::getInfo() { return info; } No* No::getProximo() { return proximo; }

Implementação dos métodos da classe Lista: Lista::Lista() { inicio = 0; } Lista::~Lista() {

if(inicio) delete inicio; inicio = 0; }

void Lista::insere_inicio_lista(int info) {

// aloca novo nó

No *novoNo = new No();

// novoNo foi alocado com sucesso? if(novoNo) {

(8)

// lista está vazia? if(lista_vazia()) inicio = novoNo; else { novoNo->setProximo(inicio); inicio = novoNo; } } }

void Lista::insere_final_lista(int info) {

// aloca novo nó

No *novoNo = new No();

// novoNo foi alocado com sucesso? if(novoNo)

{

novoNo->setInfo(info); // lista está vazia? if(lista_vazia()) inicio = novoNo; else {

// percorre começa a partir do início No *percorre = inicio;

// faz o ponteiro percorre apontar para o último nó while (percorre->getProximo() != 0)

percorre = percorre->getProximo(); // último nó aponta para o novo nó percorre->setProximo(novoNo); } } } void Lista::remove_inicio_lista() { if (!lista_vazia()) {

// o nó apontado por início deve ser removido No *noRemovido = inicio;

(9)

// inicio aponta para o segundo nó da lista inicio = inicio->getProximo();

// o nó a ser removido deve apontar para nulo noRemovido->setProximo(0);

// remover e devolver a memória para o SO delete noRemovido; } } void Lista::remove_final_lista() { No *noAnterior, *noRemover;

// lista tem pelo menos um elemento? if(!lista_vazia())

{

noAnterior = 0; noRemover = inicio;

// enquanto o nó atual tiver um próximo nó faça while(noRemover->getProximo() != 0) {

noAnterior = noRemover;

noRemover = noRemover->getProximo(); }

// nó a ser removido é o próprio início da lista if(noRemover == inicio) {

delete inicio; inicio = 0;

} else {

// o nó anterior ao último deve apontar para o próximo do nó atual

noAnterior->setProximo(noRemover->getProximo()); // o próximo do nó a ser removido aponta para nulo

noRemover->setProximo(0); // remove o nó delete noRemover; } } }

(10)

void Lista::imprime_lista() {

// nó atual é o início da lista No *noAtual = inicio;

// enquanto nó atual for diferente de nulo while(noAtual) { cout << noAtual->getInfo() << "\t"; // nó atual é o próximo nó noAtual = noAtual->getProximo(); } cout << endl; } bool Lista::lista_vazia() { // inicio é nulo? return inicio == 0; }

Implementação da função main: #include"Lista.h" #include<ctime> #include<cstdlib> #include<iostream> using namespace std; int main() {

Lista *l = new Lista();

srand(time(NULL));

cout << "Insercao no inicio da lista\n";

for(int contador=0; contador < 10; contador++) {

(11)

l->imprime_lista(); }

cout << "Remocao do inicio da lista\n";

for(int contador=0; contador < 10; contador++) {

l->remove_inicio_lista(); l->imprime_lista();

}

cout << "Insercao no final da lista\n";

for(int contador=0; contador < 10; contador++) {

l->insere_final_lista(rand() % 100); l->imprime_lista();

}

cout << "Remocao do final da lista\n";

for(int contador=0; contador < 10; contador++) { l->remove_final_lista(); l->imprime_lista(); } if (l) delete l; return 0; }

Referências

Documentos relacionados

Para isso, são realizados estudos de caso em três montadoras de motores para automóveis e em seis fornecedores; estes últimos possuem portes distintos, produzem produtos

Os estudos iniciais em escala de bancada foram realizados com um minério de ferro de baixo teor e mostraram que é possível obter um concentrado com 66% Fe e uma

Projec Projetos e Consultoria Ltda Martinópolis Em Análise 13845/07 Secretaria de Estado dos Transportes Metropolitano Implantação do Sistema Integrado Metropolitano - VLT

5. como o molde foi copiado com a pence da cintura, lembre-se de distribuir o valor da pence nas duas pregas, para que a saia não fique larga na cintura. Ou seja, se foi

Beatriz Cardoso Carla Veloso Filipe Santos João Pedro Teixeira José Manuel Teixeira Maria Júlia Lopes Pedro Granate Ricardo Frada Susana Castro

• Módulo B: representa a interface com sistemas de gerência de propriedade ( asset management ) para um serviço de distribuição multimídia. • Módulo C: representa a interface

RESULTADOS.. senciais com profissionais e estudantes de diferentes áreas. Buscou-se, ainda, o desenvolvimento de atividades educativas na comunidade voltadas para a