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

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

Listas Encadeadas Circulares Listas Duplamente Encadeadas.

Apresentações semelhantes


Apresentação em tema: "Listas Encadeadas Circulares Listas Duplamente Encadeadas."— Transcrição da apresentação:

1 Listas Encadeadas Circulares Listas Duplamente Encadeadas

2 Listas Encadeadas Circulares

3 Motivação para listas duplamente encadeadas e circulares 3

4 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

5 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

6 Listas circulares 6 Ponteiros aterrados representam listas circulares vazias

7 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 7 tmp

8 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

9 Implementação Java

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

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

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

13 Implementação C++

14 Listas circulares – Inclusão na frente template void LinkedList ::InsertFront (T const& item) { ListElement * const tmp = new ListElement (item,0); tail->next = tmp; if(tail == 0) tail = tmp; else { tmp->next = tail->next; } tail->next = tmp; } 14

15 Listas circulares – Inclusão no final template void LinkedList ::InsertFront (T const& item) { // frente será o sucessor de tail // depois tail será tail->next ListElement * const tmp = new ListElement (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

16 Listas circulares – exclusão template void LinkedList ::ExtractLast (T const& item) { if (tail == 0) throw invalid_argument "item not found"); ListElement * tmp = 0; tmp = tail->next; item = tmp->datum; tail->next = tmp->next if (tail == tmp) tail = 0; delete tmp; } 16

17 Listas Duplamente Encadeadas

18 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

19 LISTAS DUPLAMENTE ENCADEADAS 19

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

21 LISTAS DUPLAMENTE ENCADEADAS 21 Memória

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

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

24 Implementação Java

25 Classe DoubleLinkedList public class DoubleLinkedList { 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 getDatum() // obter dado { return datum; } public Element getNext() // obter sucessor { return next; } public Element getPrev() // obter antecessor { return prev; } //... } //... } 25

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

27 Métodos getHead, getTail e isEmpty public class DoubleLinkedList { protected Element head; protected Element tail; public Element getHead () // cabeça da lista { return head; } public Element getTail () // cauda da lista { return tail; } public boolean isEmpty () //teste de lista vazia { return head == null; } //... } 27

28 Métods getFirst e getLast public class DoubleLinkedList { protected Element head; protected Element tail; public Object getFirst() { // obter o primeiro elemento //da lista if(head == null) throw new ContainerEmptyException(); return head.datum; } public Object getLast() {// obter o último elemento //da lista if(tail == null) throw new ContainerEmptyException(); return tail.datum; } //... } 28

29 Método prepend public class DoubleLinkedList { 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

30 Método append public class DoubleLinkedList { 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

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

32 Método extract (1) public class DoubleLinkedList { 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 IllegalArgumentException ("item not found"); if(head == tail) { head = null; tail = null; } 32

33 Método extract (2) 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 DoubleLinkedList 33

34 Método insertAfter // Inclui item depois do objeto corrente public void insertAfter(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

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

36 Implementação C++

37 Definição das Classes DoubleLinkedList e ListElement (1) template class DoubleLinkedList; template class ListElement { T datum; ListElement* next; ListElement* prev; ListElement (T const&, ListElement*); public: T const& Datum () const; ListElement const* Next () const; ListElement const* Prev() const: friend DoubleLinkedList ; }; 37

38 Definição das Classes DoubleLinkedList e ListElement (2) template class DoubleLinkedList { ListElement * head; ListElement * tail; public: DoubleLinkedList (); ~DoubleLinkedList (); DoubleLinkedList (DoubleLinkedList const&); DoubleLinkedList& operator = (DoubleLinkedList const&); 38

39 Definição das Classes DoubleLinkedList e ListElement (3) ListElement const* Head () const; ListElement const* Tail () const; bool IsEmpty () const; T const& First () const; T const& Last () const; void Prepend (T const&); void Append (T const&); void Extract (T const&); void Purge (); void InsertAfter (ListElement const*, T const&); void InsertBefore (ListElement const*, T const&); }; 39

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

41 Construtor Default da Classe ListElement template DoubleLinkedList ::DoubleLinkedList () : head (0), tail (0) {} 41

42 Definição de Funções Membro Destrutor e Purge da Classe ListElement template void DoubleLinkedList ::Purge () { while (head != 0) { ListElement * const tmp = head; head = head->next; delete tmp; } tail = 0; } template DoubleLinkedList ::~DoubleLinkedList () { Purge (); } 42

43 Definição de Funções Accessor da Classe ListElement template ListElement const* DoubleLinkedList ::Head () const { return head; } template ListElement const* DoubleLinkedList ::Tail () const { return tail; } template bool DoubleLinkedList ::IsEmpty () const { return head == 0; } 43

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

45 Definição de Função Prepend da Classe ListElement template void DoubleLinkedList ::Prepend (T const& item) { ListElement * const tmp = new ListElement (item, head, 0); if(head == 0) tail = tmp; head->prev = tmp; head = tmp; } 45

46 Definição de Função Append da Classe ListElement template void DoubleLinkedList ::Append (T const& item) { ListElement * const tmp = new ListElement (item, 0, tail); if(head == 0) head = tmp; else tail->next = tmp; tail = tmp; } 46

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

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

49 Definição de Função Extract da Classe ListElement (1) template void DoubleLinkedList ::Extract (T const& item) { ListElement * 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

50 Definição de Função Extract da Classe ListElement (2) if(ptr == head) // exclui head { ptr->next->prev = 0; head = ptr->next; } else if(ptr == tail) //exclui tail { ptr->prev->next = 0; tail = prevPtr; } else { ptr->prev->next = ptr->next; ptr->next->prev = ptr->prev; } delete ptr; } 50

51 Definição da Função InsertAfter da Classe ListElement template void DoubleLinkedList ::InsertAfter (ListElement const* arg,T const& item) { ListElement * ptr = const_cast *> (arg); if(ptr == 0) throw invalid_argument ("invalid position"); ListElement * const tmp = new ListElement (item, ptr->next, ptr); ptr->next = tmp; if(tail == ptr) tail = tmp; else ptr->next->prev = tmp; } 51

52 Definição da Função InsertBefore da Classe ListElement (1) template void LinkedList ::InsertBefore (ListElement const* arg, T const& item) { ListElement * ptr = const_cast *> (arg); if(ptr == 0) throw invalid_argument ("invalid position"); ListElement * const tmp = new ListElement (item, ptr, ptr->prev); 52

53 Definição da Função InsertBefore da Classe ListElement (2) if(head == ptr) {ptr->prev = tmp; head = tmp; } else { ptr->prev = tmp; ptr->prev->next = tmp; } 53


Carregar ppt "Listas Encadeadas Circulares Listas Duplamente Encadeadas."

Apresentações semelhantes


Anúncios Google