Você está na página 1de 53

Listas Encadeadas Circulares

Listas Duplamente Encadeadas


Listas Encadeadas Circulares
Motivao para listas duplamente
encadeadas e circulares
3
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, no se ter
acesso aos ns que precedem o n p
Este inconveniente pode ser contornado com o
emprego de listas circulares
Listas circulares so 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 no tem um primeiro n nem
ltimo n naturais
Uma conveno til apontar o ponteiro externo
(tail para a lista circular) para o ltimo n, sendo o
conceito de ltimo vindo de tempo de incluso
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




6
Ponteiros aterrados representam listas circulares vazias
Listas circulares incluso
Incluso de um n com endereo apontado por tmp na
frente e na retaguarda de uma lista circular apontada por
tail
A incluso na retaguarda uma incluso na frente
seguida de tail tmp

7
tmp
tmp
tmp
Listas circulares excluso
Excluso do n da frente de uma lista
circular na qual tail aponta o ltimo n com
a recuperao da informao desse n em y

8
Implementao Java
Listas circulares incluso 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
Listas circulares incluso 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
Listas circulares excluso
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
Implementao C++
Listas circulares Incluso na frente
template <class T>
void LinkedList<T>::InsertFront (T const& item)
{
ListElement<T>* const tmp = new ListElement<T> (item,0);
tail->next = tmp;
if(tail == 0)
tail = tmp;
else
{
tmp->next = tail->next;
}
tail->next = tmp;
}

14
Listas circulares Incluso no final
template <class T>
void LinkedList<T>::InsertFront (T const& item)
{
// frente ser o sucessor de tail
// depois tail ser tail->next
ListElement<T>* const tmp = new ListElement<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 excluso
template <class T>
void LinkedList<T>::ExtractLast (T const& item)
{
if (tail == 0)
throw invalid_argument "item not found");
ListElement<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
Alterando-se os ns de listas encadeadas de forma
que cada n passe a contar, alm do registro de
informao e do ponteiro para o sucessor, tambm
um ponteiro para antecessor se obtm listas
duplamente encadeadas
18
LISTAS DUPLAMENTE ENCADEADAS
datum datum d a tu m datum null null
Fig. 5.7 Listas duplamente encadeadas
19
LISTAS DUPLAMENTE ENCADEADAS
Uma propriedade caracterstica das listas
duplamente encadeadas expressa por:
p.next.prev = p = p.prev.next
EXEMPLO

20
LISTAS DUPLAMENTE ENCADEADAS
Endereo prev datum next
100 NULL a 200
150 200 c 220
200 100 b 150
220 150 d 300
300 220 e NULL

21
Memria
LISTAS DUPLAMENTE ENCADEADAS

Incluso
incluso do n apontado por q direita
do n apontado por p

22
LISTAS DUPLAMENTE ENCADEADAS

Excluso
excluso do n apontado por q

23
Implementao Java
Classe DoubleLinkedList
public class DoubleLinkedList {
protected Element head; // cabea
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
Mtodos 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
Mtodos getHead, getTail e isEmpty
public class DoubleLinkedList
{
protected Element head;
protected Element tail;
public Element getHead () // cabea da lista
{ return head; }

public Element getTail () // cauda da lista
{ return tail; }

public boolean isEmpty () //teste de lista vazia
{ return head == null; }

// ...
}
27
Mtods 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
Mtodo prepend
public class DoubleLinkedList
{
protected Element head;
protected Element tail;

// inluir o objeto item no incio 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
Mtodo 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
Mtodo assign
public class DoubleLinkedList {
protected Element head;
protected Element tail;
// a lista corrente ser uma cpia 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
Mtodo 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
Mtodo 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
Mtodo 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
Mtodo 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
Implementao C++
Definio das Classes DoubleLinkedList<T>

e ListElement<T> (1)
template <class T>
class DoubleLinkedList;

template <class T>
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<T>;
};
37
Definio das Classes DoubleLinkedList<T>

e ListElement<T> (2)
template <class T>
class DoubleLinkedList
{
ListElement<T>* head;
ListElement<T>* tail;
public:
DoubleLinkedList ();
~DoubleLinkedList ();

DoubleLinkedList (DoubleLinkedList const&);
DoubleLinkedList& operator = (DoubleLinkedList const&);


38
Definio das Classes DoubleLinkedList<T>

e ListElement<T> (3)

ListElement<T> const* Head () const;
ListElement<T> 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<T> const*, T const&);
void InsertBefore (ListElement<T> const*, T const&);
};
39
Definio de Funes Membro da

Classe ListElement<T>
template <class T>
ListElement<T>::ListElement (
T const& _datum, ListElement<T>* _next, ListElement<T>* _prev) :
datum (_datum), next (_next), prev (_prev)
{}

template <class T>
T const& ListElement<T>::Datum () const
{ return datum; }

template <class T>
ListElement<T> const* ListElement<T>::Next () const
{ return next; }
ListElement<T> const* ListElement<T>::Prev () const
{ return prev; }

40
Construtor Default da Classe ListElement<T>

template <class T>
DoubleLinkedList<T>::DoubleLinkedList () :
head (0),
tail (0)
{}

41
Definio de Funes Membro Destrutor

e Purge da Classe ListElement<T>
template <class T>
void DoubleLinkedList<T>::Purge ()
{
while (head != 0)
{
ListElement<T>* const tmp = head;
head = head->next;
delete tmp;
}
tail = 0;
}
template <class T>
DoubleLinkedList<T>::~DoubleLinkedList ()
{ Purge (); }
42
Definio de Funes Accessor da Classe ListElement<T>
template <class T>
ListElement<T> const* DoubleLinkedList<T>::Head () const
{ return head; }

template <class T>
ListElement<T> const* DoubleLinkedList<T>::Tail () const
{ return tail; }

template <class T>
bool DoubleLinkedList<T>::IsEmpty () const
{ return head == 0; }
43
Definio de Funes First e Last da

Classe ListElement<T>
template <class T>
T const& DoubleLinkedList<T>::First () const
{
if(head == 0)
throw domain_error ("list is empty");
return head->datum;
}

template <class T>
T const& DoubleLinkedList<T>::Last () const
{
if(tail == 0)
throw domain_error ("list is empty");
return tail->datum;
}
44
Definio de Funo Prepend da Classe ListElement<T>

template <class T>
void DoubleLinkedList<T>::Prepend (T const& item)
{
ListElement<T>* const tmp = new ListElement<T>
(item, head, 0);
if(head == 0)
tail = tmp;
head->prev = tmp;
head = tmp;
}
45
Definio de Funo Append da Classe ListElement<T>

template <class T>
void DoubleLinkedList<T>::Append (T const& item)
{
ListElement<T>* const tmp = new ListElement<T>
(item, 0, tail);
if(head == 0)
head = tmp;
else
tail->next = tmp;
tail = tmp;
}
46
Definio de Funo Construtor Copy

da Classe ListElement<T> (1)
template <class T>
DoubleLinkedList<T>::DoubleLinkedList (DoubleLinkedList<T>
const& DoubleLinkedList) :
head (0),
tail (0),
{
ListElement<T> const* ptr;
for(ptr = DoubleLinkedList.head; ptr != 0; ptr = ptr->next)
Append (ptr->datum);
}

47
Definio de Funo Construtor Copy da

Classe ListElement<T> (2)
template <class T>
DoubleLinkedList<T>& DoubleLinkedList<T>::operator =
(DoubleLinkedList<T> const& DoubleLinkedList)
{
if(&DoubleLinkedList != this)
{
Purge ();
ListElement<T> const* ptr;
for(ptr = DoubleLinkedList.head; ptr != 0; ptr = ptr->next)
Append (ptr->datum);
}
return *this;
}
48
Definio de Funo Extract da

Classe ListElement<T> (1)
template <class T>
void DoubleLinkedList<T>::Extract (T const& item)
{
ListElement<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
Definio de Funo Extract da Classe

ListElement<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 = prevPtr;
}
else
{
ptr->prev->next = ptr->next;
ptr->next->prev = ptr->prev;
}
delete ptr;
}
50
Definio da Funo InsertAfter da

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

51
Definio da Funo InsertBefore da

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

Classe ListElement<T> (2)
if(head == ptr)
{ptr->prev = tmp;
head = tmp;
}
else
{
ptr->prev = tmp;
ptr->prev->next = tmp;
}
}

53

Você também pode gostar