Listas Encadeadas Circulares Listas Duplamente Encadeadas Listas Encadeadas

  • Slides: 53
Download presentation
Listas Encadeadas Circulares Listas Duplamente Encadeadas

Listas Encadeadas Circulares Listas Duplamente Encadeadas

Listas Encadeadas Circulares

Listas Encadeadas Circulares

Motivação para listas duplamente encadeadas e circulares 3

Motivação para listas duplamente encadeadas e circulares 3

LISTAS CIRCULARES • Um dos inconvenientes do emprego de listas encadeadas consiste no caso

LISTAS CIRCULARES • Um dos inconvenientes do emprego de listas encadeadas consiste no caso de, dado um ponteiro para um nó p de uma lista encadeada, não se ter acesso aos nós que precedem o nó p • Este inconveniente pode ser contornado com o emprego de listas circulares • Listas circulares são listas encadeadas nas quais o ponteiro do último nó deixa de ser aterrado para apontar o primeiro nó da lista 4

LISTAS CIRCULARES • Uma lista circular não tem um primeiro nó nem último nó

LISTAS CIRCULARES • Uma lista circular não tem um primeiro nó nem último nó “naturais” • Uma convenção útil é apontar o ponteiro externo (“tail” para a lista circular) para o último nó, sendo o conceito de último vindo de tempo de inclusão • O ponteiro head torna-se permanentemente aterrado e o ponteiro tail aponta o último elemento da lista • Outra alternativa consiste em usar apenas um ponteiro externo head 5

Listas circulares Ponteiros aterrados representam listas circulares vazias 6

Listas circulares Ponteiros aterrados representam listas circulares vazias 6

Listas circulares – inclusão • Inclusão de um nó com endereço apontado por tmp

Listas circulares – inclusão • Inclusão de um nó com endereço apontado por tmp na frente e na retaguarda de uma lista circular apontada por tail • A inclusão na retaguarda é uma inclusão na frente seguida de tail ← tmp tmp 7

Listas circulares – exclusão • Exclusão do nó da frente de uma lista circular

Listas circulares – exclusão • Exclusão do nó da frente de uma lista circular na qual tail aponta o último nó com a recuperação da informação desse nó em y 8

Implementação Java

Implementação Java

Listas circulares – inclusão na frente // frente será o sucessor de tail public

Listas circulares – inclusão na frente // frente será o sucessor de tail public void insert. Front(Object item){ Element tmp = new Element (item, null); if (tail = null) tail = tmp; else { tmp. next = tail. next; } tail. next = tmp; } 10

Listas circulares – inclusão no final // frente será o sucessor de tail //

Listas circulares – inclusão no final // frente será o sucessor de tail // depois tail será tail. next public void insert. Rear(Object item){ Element tmp = new Element (item, null); if (tail = null) tail = tmp; else { tmp. next = tail. next; } tail. next = tmp; tail = tmp; } 11 // transformar primeiro em último

Listas circulares – exclusão public void extract. Last(Object item) { if (tail = null)

Listas circulares – exclusão public void extract. Last(Object item) { if (tail = null) throw new Illegal. Argument. Exception ("item not found"); Element tmp = tail. next; item = tmp. datum; tail. next = tmp. next if (tail = tmp) tail = null; } 12

Implementação C++

Implementação C++

Listas circulares – Inclusão na frente template <class T> void Linked. List<T>: : Insert.

Listas circulares – Inclusão na frente template <class T> void Linked. List<T>: : Insert. Front (T const& item) { List. Element<T>* const tmp = new List. Element<T> (item, 0); tail->next = tmp; if(tail == 0) tail = tmp; else { tmp->next = tail->next; } tail->next = tmp; } 14

Listas circulares – Inclusão no final template <class T> void Linked. List<T>: : Insert.

Listas circulares – Inclusão no final template <class T> void Linked. List<T>: : Insert. Front (T const& item) { // frente será o sucessor de tail // depois tail será tail->next List. Element<T>* const tmp = new List. Element<T> (item, 0); ptr->next = tmp; if(tail == 0) tail = tmp; else { tmp->next = tail->next; } tail->next = tmp; tail = tmp; // transformar primeiro em último } 15

Listas circulares – exclusão template <class T> void Linked. List<T>: : Extract. Last (T

Listas circulares – exclusão template <class T> void Linked. List<T>: : Extract. Last (T const& item) { if (tail == 0) throw invalid_argument "item not found"); List. Element<T>* tmp = 0; tmp = tail->next; item = tmp->datum; tail->next = tmp->next if (tail == tmp) tail = 0; delete tmp; } 16

Listas Duplamente Encadeadas

Listas Duplamente Encadeadas

LISTAS DUPLAMENTE ENCADEADAS • Alterando-se os nós de listas encadeadas de forma que cada

LISTAS DUPLAMENTE ENCADEADAS • Alterando-se os nós de listas encadeadas de forma que cada nó passe a contar, além do registro de informação e do ponteiro para o sucessor, também um ponteiro para antecessor se obtém listas duplamente encadeadas 18

LISTAS DUPLAMENTE ENCADEADAS 19

LISTAS DUPLAMENTE ENCADEADAS 19

LISTAS DUPLAMENTE ENCADEADAS • Uma propriedade característica das listas duplamente encadeadas é expressa por:

LISTAS DUPLAMENTE ENCADEADAS • Uma propriedade característica das listas duplamente encadeadas é expressa por: p. next. prev = p. prev. next • EXEMPLO 20

LISTAS DUPLAMENTE ENCADEADAS Memória 21

LISTAS DUPLAMENTE ENCADEADAS Memória 21

LISTAS DUPLAMENTE ENCADEADAS – Inclusão • inclusão do nó apontado por q à direita

LISTAS DUPLAMENTE ENCADEADAS – Inclusão • inclusão do nó apontado por q à direita do nó apontado por p 22

LISTAS DUPLAMENTE ENCADEADAS – Exclusão • exclusão do nó apontado por q 23

LISTAS DUPLAMENTE ENCADEADAS – Exclusão • exclusão do nó apontado por q 23

Implementação Java

Implementação Java

Classe Double. Linked. List public class Double. Linked. List { protected Element head; //

Classe Double. Linked. List public class Double. Linked. List { protected Element head; // cabeça protected Element tail; // cauda public final class Element { // elemento do lista Object datum; // dado do elemento ou item Element next; // ponteiro para sucessor Element prev; // ponteiro para antecessor Element(Object datum, Element next, Element prev) { // construtor this. datum = datum; this. next = next; this. prev = prev; } public Object get. Datum() // obter dado { return datum; } public Element get. Next() // obter sucessor { return next; } public Element get. Prev() // obter antecessor { return prev; } //. . . } 25

Métodos Construtor e purge public class Double. Linked. List { protected Element head; protected

Métodos Construtor e purge public class Double. Linked. List { protected Element head; protected Element tail; public Double. Linked. List () // construir uma lista {} public void purge () { head = null; tail = null; } //. . . } 26 // esvaziar uma lista

Métodos get. Head, get. Tail e is. Empty public class Double. Linked. List {

Métodos get. Head, get. Tail e is. Empty public class Double. Linked. List { protected Element head; protected Element tail; public Element get. Head () // cabeça da lista { return head; } public Element get. Tail () // cauda da lista { return tail; } public boolean is. Empty () { return head == null; } //. . . } 27 //teste de lista vazia

Métods get. First e get. Last public class Double. Linked. List { protected Element

Métods get. First e get. Last public class Double. Linked. List { protected Element head; protected Element tail; public Object get. First() { // obter o primeiro elemento //da lista if(head == null) throw new Container. Empty. Exception(); return head. datum; } public Object get. Last() { // obter o último elemento //da lista if(tail == null) throw new Container. Empty. Exception(); return tail. datum; } //. . . } 28

Método prepend public class Double. Linked. List { protected Element head; protected Element tail;

Método prepend public class Double. Linked. List { protected Element head; protected Element tail; // inluir o objeto item no início da lista corrente public void prepend(Object item) { Element tmp = new Element(item, head, null); if(head == null) tail = tmp; head. prev = tmp; head = tmp; } //. . . } 29

Método append public class Double. Linked. List { protected Element head; protected Element tail;

Método append public class Double. Linked. List { protected Element head; protected Element tail; // incluir o objeto item no final da lista corrente public void append (Object item) { Element tmp = new Element (item, null, tail); if(head == null) head = tmp; else tail. next = tmp; tail = tmp; } //. . . } 30

Método assign public class Double. Linked. List { protected Element head; protected Element tail;

Método assign public class Double. Linked. List { protected Element head; protected Element tail; // a lista corrente será uma cópia da list public void assign(Double. Linked. List list) { if(list != this) { purge (); for(Element ptr = list. head; ptr != null; ptr = ptr. next) { append (ptr. datum); } } } //. . . } 31

Método extract (1) public class Double. Linked. List { protected Element head; protected Element

Método extract (1) public class Double. Linked. List { protected Element head; protected Element tail; // Exclui objeto item public void extract(Object item) { Element ptr = head; while(ptr != null && ptr. datum != item) { ptr = ptr. next; } if(ptr == null) throw new Illegal. Argument. Exception ("item not found"); if(head == tail) { head = null; tail = null; } 32

Método extract (2) } 33 if(ptr == head) // exclui head { ptr. next.

Método extract (2) } 33 if(ptr == head) // exclui head { ptr. next. prev = null; head = ptr. next; } else if(ptr == tail) // exclui tail { ptr. prev. next = null; tail = ptr. prev; } else { ptr. prev. next = ptr. next; ptr. next. prev = ptr. prev; } } // fim do extract // fim da classe Double. Linked. List

Método insert. After // Inclui item depois do objeto corrente public void insert. After(Object

Método insert. After // Inclui item depois do objeto corrente public void insert. After(Object item) { Element tmp = new Element (item, next, this); if(tail == this){ this. next = tmp; tail = tmp; } else { this. next. prev = tmp; this. next = tmp; } } 34

Método insert. Before // Inclui item antes do objeto corrente public void insert. Before(Object

Método insert. Before // Inclui item antes do objeto corrente public void insert. Before(Object item) { Element tmp = new Element(item, this. prev); if(head == this) { this. prev = tmp; head = tmp; } else { prev. next = tmp; this. prev = tmp; } } //. . . } 35

Implementação C++

Implementação C++

Definição das Classes Double. Linked. List<T> e List. Element<T> (1) template <class T> class

Definição das Classes Double. Linked. List<T> e List. Element<T> (1) template <class T> class Double. Linked. List; template <class T> class List. Element { T datum; List. Element* next; List. Element* prev; List. Element (T const&, List. Element*); public: T const& Datum () const; List. Element const* Next () const; List. Element const* Prev() const: friend Double. Linked. List<T>; }; 37

Definição das Classes Double. Linked. List<T> e List. Element<T> (2) template <class T> class

Definição das Classes Double. Linked. List<T> e List. Element<T> (2) template <class T> class Double. Linked. List { List. Element<T>* head; List. Element<T>* tail; public: Double. Linked. List (); ~Double. Linked. List (); Double. Linked. List (Double. Linked. List const&); Double. Linked. List& operator = (Double. Linked. List const&); 38

Definição das Classes Double. Linked. List<T> e List. Element<T> (3) List. Element<T> const* Head

Definição das Classes Double. Linked. List<T> e List. Element<T> (3) List. Element<T> const* Head () const; List. Element<T> const* Tail () const; bool Is. Empty () const; T const& First () const; T const& Last () const; void void }; 39 Prepend (T const&); Append (T const&); Extract (T const&); Purge (); Insert. After (List. Element<T> const*, T const&); Insert. Before (List. Element<T> const*, T const&);

Definição de Funções Membro da Classe List. Element<T> template <class T> List. Element<T>: :

Definição de Funções Membro da Classe List. Element<T> template <class T> List. Element<T>: : List. Element ( T const& _datum, List. Element<T>* _next, List. Element<T>* _prev) : datum (_datum), next (_next), prev (_prev) {} template <class T> T const& List. Element<T>: : Datum () const { return datum; } template <class T> List. Element<T> const* List. Element<T>: : Next () const { return next; } List. Element<T> const* List. Element<T>: : Prev () const { return prev; } 40

Construtor Default da Classe List. Element<T> template <class T> Double. Linked. List<T>: : Double.

Construtor Default da Classe List. Element<T> template <class T> Double. Linked. List<T>: : Double. Linked. List () : head (0), tail (0) {} 41

Definição de Funções Membro Destrutor e Purge da Classe List. Element<T> template <class T>

Definição de Funções Membro Destrutor e Purge da Classe List. Element<T> template <class T> void Double. Linked. List<T>: : Purge () { while (head != 0) { List. Element<T>* const tmp = head; head = head->next; delete tmp; } tail = 0; } template <class T> Double. Linked. List<T>: : ~Double. Linked. List () { Purge (); } 42

Definição de Funções Accessor da Classe List. Element<T> template <class T> List. Element<T> const*

Definição de Funções Accessor da Classe List. Element<T> template <class T> List. Element<T> const* Double. Linked. List<T>: : Head () const { return head; } template <class T> List. Element<T> const* Double. Linked. List<T>: : Tail () const { return tail; } template <class T> bool Double. Linked. List<T>: : Is. Empty () const { return head == 0; } 43

Definição de Funções First e Last da Classe List. Element<T> template <class T> T

Definição de Funções First e Last da Classe List. Element<T> template <class T> T const& Double. Linked. List<T>: : First () const { if(head == 0) throw domain_error ("list is empty"); return head->datum; } template <class T> T const& Double. Linked. List<T>: : Last () const { if(tail == 0) throw domain_error ("list is empty"); return tail->datum; } 44

Definição de Função Prepend da Classe List. Element<T> template <class T> void Double. Linked.

Definição de Função Prepend da Classe List. Element<T> template <class T> void Double. Linked. List<T>: : Prepend (T const& item) { List. Element<T>* const tmp = new List. Element<T> (item, head, 0); if(head == 0) tail = tmp; head->prev = tmp; head = tmp; } 45

Definição de Função Append da Classe List. Element<T> template <class T> void Double. Linked.

Definição de Função Append da Classe List. Element<T> template <class T> void Double. Linked. List<T>: : Append (T const& item) { List. Element<T>* const tmp = new List. Element<T> (item, 0, tail); if(head == 0) head = tmp; else tail->next = tmp; tail = tmp; } 46

Definição de Função Construtor Copy da Classe List. Element<T> (1) template <class T> Double.

Definição de Função Construtor Copy da Classe List. Element<T> (1) template <class T> Double. Linked. List<T>: : Double. Linked. List (Double. Linked. List<T> const& Double. Linked. List) : head (0), tail (0), { List. Element<T> const* ptr; for(ptr = Double. Linked. List. head; ptr != 0; ptr = ptr->next) Append (ptr->datum); } 47

Definição de Função Construtor Copy da Classe List. Element<T> (2) template <class T> Double.

Definição de Função Construtor Copy da Classe List. Element<T> (2) template <class T> Double. Linked. List<T>& Double. Linked. List<T>: : operator = (Double. Linked. List<T> const& Double. Linked. List) { if(&Double. Linked. List != this) { Purge (); List. Element<T> const* ptr; for(ptr = Double. Linked. List. head; ptr != 0; ptr = ptr->next) Append (ptr->datum); } return *this; } 48

Definição de Função Extract da Classe List. Element<T> (1) template <class T> void Double.

Definição de Função Extract da Classe List. Element<T> (1) template <class T> void Double. Linked. List<T>: : Extract (T const& item) { List. Element<T>* ptr = head; while(ptr != 0 && ptr->datum != item) { ptr = ptr->next; } if(ptr == 0) throw invalid_argument ("item not found"); if(head == tail) // exclui head { head= 0; tail = 0; } 49

Definição de Função Extract da Classe List. Element<T> (2) if(ptr == head) // exclui

Definição de Função Extract da Classe List. Element<T> (2) if(ptr == head) // exclui head { ptr->next->prev = 0; head = ptr->next; } else if(ptr == tail) //exclui tail { ptr->prev->next = 0; tail = prev. Ptr; } else { ptr->prev->next = ptr->next; ptr->next->prev = ptr->prev; } delete ptr; } 50

Definição da Função Insert. After da Classe List. Element<T> template <class T> void Double.

Definição da Função Insert. After da Classe List. Element<T> template <class T> void Double. Linked. List<T>: : Insert. After (List. Element<T> const* arg, T const& item) { List. Element<T>* ptr = const_cast<List. Element<T>*> (arg); if(ptr == 0) throw invalid_argument ("invalid position"); List. Element<T>* const tmp = new List. Element<T> (item, ptr->next, ptr); ptr->next = tmp; if(tail == ptr) tail = tmp; else ptr->next->prev = tmp; } 51

Definição da Função Insert. Before da Classe List. Element<T> (1) template <class T> void

Definição da Função Insert. Before da Classe List. Element<T> (1) template <class T> void Linked. List<T>: : Insert. Before (List. Element<T> const* arg, T const& item) { List. Element<T>* ptr = const_cast<List. Element<T>*> (arg); if(ptr == 0) throw invalid_argument ("invalid position"); List. Element<T>* const tmp = new List. Element<T> (item, ptr->prev); 52

Definição da Função Insert. Before da Classe List. Element<T> (2) if(head == ptr) {ptr->prev

Definição da Função Insert. Before da Classe List. Element<T> (2) if(head == ptr) {ptr->prev = tmp; head = tmp; } else { ptr->prev = tmp; ptr->prev->next = tmp; } } 53