Pilhas e Filas

Download Report

Transcript Pilhas e Filas

Pilhas e Filas
Sumário
Definição
 Pilhas
 Filas
Implementação Java
Implementação C++
2
Sumário
Implementação Java
 Fundamentos
 Pilhas
 Implementação
 Implementação
 Filas
 Implementação
 Implementação
Implementação C++
 Fundamentos
 Pilhas
 Implementação
 Implementação
 Filas
 Implementação
 Implementação
por arrays
por listas encadeadas
por arrays
por listas encadeadas
por arrays
por listas encadeadas
por arrays
por listas encadeadas
3
Definição
Pilhas
Conceito de Pilha (1)
Pilha é o mais simples dos containers.
A operação de inclusão de elementos na pilha recebe o nome de
empilhamento (push) e a operação de exclusão recebe o nome
de desempilhamento (pop)
Um elemento empilhado vai ocupar a posição chamada de topo
da pilha
Uma operação de desempilhamento provoca a exclusão do
elemento no topo da pilha. Por esta razão as pilhas são
chamadas de listas LIFO ( de “Last In First Out’).
Uma operação de desempilhamento em uma pilha vazia não
tem sentido e configura uma situação denominada “underflow”
Pode-se verificar se uma pilha atingir a condição de contorno de
pilha vazia através da função isEmpty que pode assumir os
valores TRUE (pilha vazia) ou FALSE (pilha não vazia)
6
Conceito de Pilha (2)
Operações de empilhamento podem levar à situação na qual o
numero de elementos na pilha seja igual ao número máximo de
elementos comportados pelo container
Tentativas subseqüentes de empilhamento são impossíveis e
configuram situação de transbordamento ou “overflow”
A situação de “underflow” é lógica e impossível de ser
contornada. Freqüentemente não constitui erro de algoritmo e
sim teste de uma condição
A situação de “overflow” é física e não lógica
 Pode ser contornada aumentando o tamanho do container”
hospedeiro
 Contudo, durante o processamento configura um erro e
deve interromper o processo
7
Conceito de Pilha (3)
Uma operação adicional sobre pilhas é a verificação do
elemento no topo da pilha getTop.
Exemplos do dia a dia:
 Pilhas de pratos
 Pilhas de revistas
8
Conceito de Pilha (4)
9
Filas
Conceito de Fila
Fila é um container no qual todas as inclusões são efetuadas
em uma extremidade chamada de retaguarda e todas as
exclusões são efetuadas na outra extremidade denominada
frente.
Como nas filas o primeiro elemento a entrar é o primeiro a sair,
as filas são chamadas de listas FIFO (de First-In, First-Out).
Exemplos do dia a dia:
 Filas de bancos
 Filas de ônibus
11
Implementação por Arrays (1)
A formulação espontânea contém dois ponteiros
frente e retaguarda ou head e tail
Inicia-se a fila com a condição de contorno head =
0 e tail = -1
Caracteriza-se fila vazia quando tail < head
Fila cheia ocorre quando tail = array.length-1,
onde array.length é o número máximo de
elementos previstos no “array”.
Como as listas podem “correr na memória” este
esquema não é eficiente
É mais vantajoso adotar filas circulares onde o
primeiro elemento sucede o último e a
implementação é feita por aritmética modular
12
Implementação por Arrays (2)
O ajustamento de ponteiros por ocasião de inclusões e
exclusões se torna diferente
Inclusão:
 tail (tail + 1) mod array.length ao invés de
tail  tail + 1
Exclusão:
 head (head + 1 ) mod array.length ao invés de
head  head + 1
A fila vazia seria caracterizada por head = tail e a fila cheia
também, o que não é satisfatório
Pode-se melhorar esta solução apontando head para a posição
do “array” precedendo o primeiro elemento da fila. Esta será a
opção adotada
A condição de file cheia se torna
head = = (tail + 1) mod array.length
13
Implementação por Arrays (3)
A solução adotada pelo Framework de Bruno Preiss para as filas
circulares é adotar a mesma condição de contorno tanto para
fila cheia como para fila vazia
head = tail
A diferença entre um caso e outro é dada pelo contador count
sendo count == array.length para fila cheia e
count == 0 para fila vazia
Esta solução permite a ocupação de todos os espaços do array
enquanto a solução sem usar count (o conteúdo do container)
exige que uma posição do array permaneça desocupada antes
do início da fila
14
Exemplo de Fila
15
Filas circulares
16
Hierarquia de Classes
para implementação no
Framework de Bruno Preiss
Java
C++
18
Implementação Java
Hierarquia de Classes
20
Fundamentos
Interface Comparable
public interface Comparable
{
boolean isLT (Comparable object);
boolean isLE (Comparable object);
boolean isGT (Comparable object);
boolean isGE (Comparable object);
boolean isEQ (Comparable object);
boolean isNE (Comparable object);
int compare (Comparable object);
}
22
Classe abstrata AbstractObject (1)
// pgm05_02.java
public abstract class AbstractObject implements Comparable
{
public final boolean isLT (Comparable object)
{ return compare (object) < 0; }
public final boolean isLE (Comparable object)
{ return compare (object) <= 0; }
public final boolean isGT (Comparable object)
{ return compare (object) > 0; }
public final boolean isGE (Comparable object)
{ return compare (object) >= 0; }
public final boolean isEQ (Comparable object)
{ return compare (object) == 0; }
public final boolean isNE (Comparable object)
{ return compare (object) != 0; }
23
Classe abstrata AbstractObject (2)
public final boolean equals (Object object) {
if(object instanceof Comparable)
return isEQ ((Comparable) object);
else
return false;
}
public final int compare (Comparable arg) {
if(getClass () == arg.getClass())
return compareTo (arg);
else
return getClass().getName().compareTo(
arg.getClass().getName() );
}
protected abstract int compareTo (Comparable arg);
}
24
Interface Container
public interface Container
extends Comparable
{
int getCount ();
boolean isEmpty ();
boolean isFull ();
void purge ();
void accept (Visitor visitor);
Enumeration getEnumeration ();
}
25
Classe Abstrata AbstractContainer
public abstract class AbstractContainer
extends AbstractObject
implements Container
{
protected int count;
public int getCount ()
{ return count; }
public boolean isEmpty ()
{ return getCount () == 0; }
public boolean isFull ()
{ return false; }
// ...
}
26
Interface Stack
//
pgm06_01.java
public interface Stack
extends Container
{
Object getTop ();
void push (Object object);
Object pop ();
}
27
Interface Queue
//
pgm06_13.java
public interface Queue
extends Container
{
Object getHead ();
void enqueue (Object object);
Object dequeue ();
}
28
Pilhas
Pilhas Implementadas em Java
Utilizando Arrays
Definição da Classe StackAsArray
//
pgm06_02.txt
public class StackAsArray
extends AbstractContainer
implements Stack
{
protected Object[] array;
// ...
}
31
Métodos Construtor e purge da
Classe StackAsArray
// pgm06_03.java
public class StackAsArray
extends AbstractContainer implements Stack
{
protected Object[] array;
public StackAsArray (int size)
{ array = new Object [size]; }
public void purge ()
{
while (count > 0)
array [--count] = null;
}
// ...
}
32
Métodos push, pop e getTop da
Classe StackAsArray (1)
// pgm06_04.java
public class StackAsArray
extends AbstractContainer implements Stack
{
protected Object[] array;
public void push (Object object)
{
if(count == array.length)
throw new ContainerFullException();
array [count++] = object;
}
33
Métodos push, pop e getTop da
Classe StackAsArray (2)
// pgm06_04.java (Continuação)
public Object pop ()
{
if(count == 0)
throw new ContainerEmptyException();
Object result = array [--count];
array[count] = null;
return result;
}
public Object getTop ()
{
if(count == 0)
throw new ContainerEmptyException ();
return array [count - 1];
}
// ...
}
34
Método accept da Classe
StackAsArray
// pgm06_05.java
public class StackAsArray
extends AbstractContainer implements Stack
{
protected Object[] array;
public void accept (Visitor visitor)
{
for (int i = 0; i < count; ++i)
{
visitor.visit (array [i]);
if(visitor.isDone ())
return;
}
}
// ...
}
35
Exemplo de uso de Enumeração (1)
Considere-se o código que se segue
Stack stack = new StackAsArray (57);
stack.push (new Integer (3));
stack.push (new Integer (1));
stack.push (new Integer (4));
Enumeration e = stack.getEnumeration ();
while (e.hasMoreElements ())
{
Object obj = e.nextElement ();
System.out.println (obj);
}
36
Exemplo de uso de Enumeração (2)
Este código cria uma instância da classe StackAsArray e a
atribui à variável stack.
Diversos objetos do tipo Integer são empilhados.
Finalmente uma enumeração é usada para imprimir de maneira
sistemática todos os objetos na pilha.
37
Classes interiores
Uma classe interior é uma classe definida dentro de outra.
A menos que seja declarada estática, cada instância de uma
classe interior é suposta dentro de uma instância da classe
exterior sendo as classes interiores não estáticas por default.
Instâncias de classes interiores podem invocar métodos de
instâncias da classe exterior e ter acesso a seus
membros.membros.
Pode haver mais de uma instância de classe interior para uma
instância de classe exterior.
Uma classe anônima é uma classe sem nome.
Estas classes são criadas estendendo uma classe existente ou
implementando uma interface bem no ponto do código aonde a
classe está sendo instanciada.
38
Método getEnumeration da Classe
StackAsArray
// pgm06_06.java
public class StackAsArray
extends AbstractContainer implements Stack {
protected Object[] array;
public Enumeration getEnumeration() {
return new Enumeration() {
protected int position = 0;
public boolean hasMoreElements()
{ return position < getCount (); }
public Object nextElement() {
if(position >= getCount ())
throw new NoSuchElementException();
return array [position++];
}
};
}
}
39
Pilhas Implementadas em Java
Utilizando Listas Encadeadas
Definição da Classe
StackAsLinkedList
// pgm06_07.java
public class StackAsLinkedList
extends AbstractContainer
implements Stack
{
protected LinkedList list;
// ...
}
41
Métodos Construtor e purge da
Classe StackAsLinkedList
// pgm06_08.java
public class StackAsLinkedList
extends AbstractContainer implements Stack
{
protected LinkedList list;
public StackAsLinkedList ()
{ list = new LinkedList (); }
public void purge ()
{
list.purge ();
count = 0;
}
// ...
}
42
Métodos push, pop e getTop da
Classe StackAsLinkedList (1)
// pgm06_09.java
public class StackAsLinkedList
extends AbstractContainer
implements Stack
{
protected LinkedList list;
public void push (Object object)
{
list.prepend (object);
++count;
}
43
Métodos push, pop e getTop da
Classe StackAsLinkedList (2)
// pgm06_09.java (Continuação)
public Object pop ()
{
if(count == 0)
throw new ContainerEmptyException ();
Object result = list.getFirst ();
list.extract (result);
--count;
return result;
}
public Object getTop ()
{
if(count == 0)
throw new ContainerEmptyException ();
return list.getFirst ();
}
// ...
}
44
Método accept da Classe
StackAsLinkedList
// pgm06_10.java
public class StackAsLinkedList
extends AbstractContainer implements Stack
{
protected LinkedList list;
public void accept (Visitor visitor) {
for(LinkedList.Element ptr = list.getHead ();
ptr != null; ptr = ptr.getNext ()) {
visitor.visit (ptr.getDatum ());
if(visitor.isDone ())
return;
}
}
// ...
}
45
Método getEnumeration da Classe
StackAsLinkedList (1)
// pgm06_11.java
public class StackAsLinkedList
extends AbstractContainer
implements Stack
{
protected LinkedList list;
46
Método getEnumeration da Classe
StackAsLinkedList (1)
// pgm06_11.java (Continuação)
}
public Enumeration getEnumeration () {
return new Enumeration () {
protected LinkedList.Element position =list.getHead();
public boolean hasMoreElements ()
{ return position != null; }
public Object nextElement () {
if(position == null)
throw new NoSuchElementException ();
Object result = position.getDatum ();
position = position.getNext ();
return result;
}
};
}
// ...
47
Filas
Filas Implementadas em Java
Utilizando Arrays
Definição da Classe QueueAsArray
// pgm06_14.java
public class QueueAsArray
extends AbstractContainer
implements Queue
{
protected Object[] array;
protected int head;
protected int tail;
// ...
}
50
Métodos construtor e purge da
Classe QueueAsArray (1)
// pgm06_15.java
public class QueueAsArray
extends AbstractContainer
implements Queue
{
protected Object[] array;
protected int head;
protected int tail;
public QueueAsArray (int size)
{
array = new Object [size];
head = 0;
tail = size - 1;
}
51
Métodos construtor e purge da
Classe QueueAsArray (2)
// pgm06_15.java (Continuação)
public void purge ()
{
while (count > 0)
{
array [head] = null;
if (++head == array.length)
head = 0;
--count;
}
}
// ...
}
52
Métodos getHead, enqueue e
dequeue da Classe QueueAsArray (1)
// pgm06_16.java
public class QueueAsArray
extends AbstractContainer
implements Queue
{
protected Object[] array;
protected int head;
protected int tail;
public Object getHead ()
{
if(count == 0)
throw new ContainerEmptyException ();
return array [head];
}
53
Métodos getHead, enqueue e
dequeue da Classe QueueAsArray (2)
public void enqueue (Object object) {
if(count == array.length)
throw new ContainerFullException ();
if(++tail == array.length)
tail = 0;
array [tail] = object;
++count;
}
public Object dequeue () {
if(count == 0)
throw new ContainerEmptyException ();
Object result = array [head];
array [head] = null;
if(++head == array.length)
head = 0;
--count;
return result;
} // ...
}
54
Filas Implementadas em Java
Utilizando Listas Encadeadas
Definição da Classe
QueueAsLinkedList
// pgm06_17.java
public class QueueAsLinkedList
extends AbstractContainer
implements Queue
{
protected LinkedList list;
// ...
}
56
Métodos construtor e purge da
Classe QueueAsLinkedList
// pgm06_18.java
public class QueueAsLinkedList
extends AbstractContainer
implements Queue
{
protected LinkedList list;
public QueueAsLinkedList ()
{ list = new LinkedList (); }
public void purge ()
{
list.purge ();
count = 0;
}
// ...
}
57
Métodos getHead, enqueue e
dequeue da Classe
QueueAsLinkedList (1)
// pgm06_19.java
public class QueueAsLinkedList
extends AbstractContainer
implements Queue
{
protected LinkedList list;
public Object getHead ()
{
if(count == 0)
throw new ContainerEmptyException ();
return list.getFirst ();
}
58
Métodos getHead, enqueue e
dequeue da Classe
QueueAsLinkedList (2)
// pgm06_19.java (Continuação)
public void enqueue (Object object)
{
list.append (object);
++count;
}
public Object dequeue ()
{
if(count == 0)
throw new ContainerEmptyException ();
Object result = list.getFirst ();
list.extract(result);
--count;
return result;
}
// ...
}
59
Implementação C++
Hierarquia de Classes
61
Fundamentos
Definição da Classe Object
// pgm05_01.cpp
class Object
{
protected:
virtual int CompareTo (Object const&) const = 0;
public:
virtual ~Object ();
virtual bool IsNull () const;
virtual int Compare (Object const&) const;
virtual HashValue Hash () const = 0;
virtual void Put (ostream&) const = 0;
};
63
Operadores da Classe Object
// pgm05_02.cpp
inline bool operator == (Object const& left, Object const& right)
{ return left.Compare (right) == 0; }
inline bool operator != (Object const& left, Object const& right)
{ return left.Compare (right) != 0; }
inline bool operator <= (Object const& left, Object const& right)
{ return left.Compare (right) <= 0; }
inline bool operator < (Object const& left, Object const& right)
{ return left.Compare (right) < 0; }
inline bool operator >= (Object const& left, Object const& right)
{ return left.Compare (right) >= 0; }
inline bool operator > (Object const& left, Object const& right)
{ return left.Compare (right) > 0; }
inline ostream& operator << (ostream& s, Object const& object)
{ object.Put (s); return s; }
64
Funções membro da Classe Object
// pgm05_03.cpp
#include <typeinfo>
Object::~Object ()
{}
bool Object::IsNull () const
{ return false; }
int Object::Compare (Object const& object) const
{
if(typeid (*this) == typeid (object))
return CompareTo (object);
else
if(typeid (*this).before (typeid (object)))
return -1;
else
return 1;
}
65
Definição da Classe NullObject
//pgm05_04.cpp
class NullObject : public Object
{
static NullObject instance;
NullObject ();
protected:
int CompareTo (Object const&) const;
public:
bool IsNull () const;
HashValue Hash () const;
void Put (ostream& s) const;
static NullObject& Instance ();
};
66
Funções membro da Classe
NullObject
//pgm05_05.cpp
NullObject NullObject::instance;
NullObject::NullObject ()
{}
bool NullObject::IsNull () const
{ return true; }
int NullObject::CompareTo (Object const&) const
{ return 0; }
HashValue NullObject::Hash () const
{ return 0; }
void NullObject::Put (ostream& s) const
{ s << "NullObject"; }
NullObject& NullObject::Instance ()
{ return instance; }
67
Definição da Classe Wrapper<T>
//pgm05_06.cpp
template <class T>
class Wrapper : public Object
{
protected:
T datum;
int CompareTo (Object const&) const;
public:
Wrapper ();
Wrapper (T const&);
Wrapper& operator = (T const&);
operator T const& () const;
HashValue Hash() const;
void Put(ostream&) const;
};
68
Funções membro da Classe
Wrapper<T> (1)
//pgm05_07.cpp
template <class T>
Wrapper<T>::Wrapper () :
datum ()
{}
template <class T>
Wrapper<T>::Wrapper (T const& d) :
datum (d)
{}
template <class T>
Wrapper<T>& Wrapper<T>::operator = (T const& d)
{
datum = d;
return *this;
}
69
Funções membro da Classe
Wrapper<T> (2)
//pgm05_07.cpp (Continuação)
template <class T>
Wrapper<T>::operator T const& () const
{ return datum; }
template <class T>
int Wrapper<T>::CompareTo (Object const& obj) const
{
Wrapper<T> const& arg = dynamic_cast<Wrapper<T> const&> (obj);
return ::Compare (datum, arg.datum);
}
template <class T>
void Wrapper<T>::Put (ostream& s) const
{ s << datum; }
70
Definição da Classe Container
//
pgm05_09.cpp
class Container : public virtual Object, public virtual
Ownership
{
protected:
unsigned int count;
Container ();
public:
virtual unsigned int Count () const;
virtual bool IsEmpty () const;
virtual bool IsFull () const;
virtual HashValue Hash () const;
virtual void Put (ostream&) const;
virtual Iterator& NewIterator () const;
virtual void Purge () = 0;
virtual void Accept (Visitor&) const = 0;
};
71
Funções membro da Classe
Container
//pgm05_10.cpp
Container::Container () :
count (0)
{}
unsigned int Container::Count () const
{ return count; }
bool Container::IsEmpty () const
{ return Count () == 0; }
bool Container::IsFull () const
{ return false; }
72
Definição da Classe Visitor
//pgm05_11.cpp
class Visitor
{
public:
virtual void Visit (Object&) = 0;
virtual bool IsDone () const
{ return false; }
};
73
Função Put da Classe Container (1)
//pgm05_12.cpp
#include <typeinfo>
class PuttingVisitor : public Visitor
{
ostream& stream;
bool comma;
public:
PuttingVisitor (ostream& s) : stream (s), comma (false) {}
void Visit (Object& object)
{
if (comma)
stream << ", ";
stream << object;
comma = true;
}
74
};
Função Put da Classe Container (2)
// pgm05_12.cpp (Conyinuação)
void Container::Put (ostream& s) const
{
PuttingVisitor visitor (s);
s << typeid (*this).name () << " {";
Accept (visitor);
s << "}";
}
75
Definição da Classe Iterator
//pgm05_13.cpp
class Iterator
{
public:
virtual ~Iterator ();
virtual void Reset () = 0;
virtual bool IsDone () const = 0;
virtual Object& operator * () const = 0;
virtual void operator ++ () = 0;
};
76
Funções membro da Classe Iterator
Iterator& SomeContainer::NewIterator () const
{ return *new SomeIterator (*this); }
SomeContainer c;
Iterator& i = c.NewIterator ();
while (!i.IsDone ()) {
cout << *i << endl;
++i;
}
delete &i;
77
Definição da Classe NullIterator
//pgm05_14.cpp
class NullIterator : public Iterator
{
public:
NullIterator ();
void Reset ();
bool IsDone () const;
Object& operator * () const;
void operator ++ ();
};
78
Funções membro da Classe
NullIterator
//pgm05_15.cpp
NullIterator::NullIterator ()
{}
void NullIterator::Reset ()
{}
bool NullIterator::IsDone () const
{ return true; }
Object& NullIterator::operator * () const
{ return NullObject::Instance (); }
void NullIterator::operator ++ ()
{}
// pgm05_16.cpp
Iterator& Container::NewIterator () const
{ return *new NullIterator (); }
79
Definição da Classe Stack
// pgm06_01.cpp
class Stack
{
public:
virtual
virtual
virtual
};
: public virtual Container
Object& Top () const = 0;
void Push (Object&) = 0;
Object& Pop () = 0;
80
Pilhas
Pilhas Implementadas em C++
Utilizando Arrays
Definição da Classe Stack
//
pgm06_01.cpp
class Stack
{
public:
virtual
virtual
virtual
};
: public virtual Container
Object& Top () const = 0;
void Push (Object&) = 0;
Object& Pop () = 0;
83
Definição da Classe StackAsArray
A variável array é declarada instanciando o template da classe
Array<T> com T=Object*, ou seja, um array de ponteiros para
Object
O uso de ponteiros é consistente com a implementação de
containers por armazenamento indireto
84
Definição da Classe StackAsArray
//
pgm06_02.cpp
class StackAsArray : public Stack {
Array<Object*> array;
class Iter;
public:
StackAsArray (unsigned int);
// ...
friend class Iter;
};
class StackAsArray::Iter : public Iterator {
StackAsArray const& stack;
unsigned int position;
public:
Iter (StackAsArray const&);
// ...
};
85
Funções membro Construtor,
Destrutor e Purge da Classe
StackAsArray
//
pgm06_03.cpp
StackAsArray::StackAsArray (unsigned int size) :
array(size)
{}
void StackAsArray::Purge ()
{
if(IsOwner ())
{
for(unsigned int i = 0; i < count; ++i)
delete array [i];
}
count = 0;
}
StackAsArray::~StackAsArray ()
{ Purge (); }
86
Funções membro Push, Pop e Top da
Classe StackAsArray
//
pgm06_04.cpp
void StackAsArray::Push (Object& object) {
if(count == array.Length ())
throw domain_error ("stack is full");
array [count++] = &object;
}
Object& StackAsArray::Pop (){
if(count == 0)
throw domain_error ("stack is empty");
return *array [--count];
}
Object& StackAsArray::Top () const{
if(count == 0)
throw domain_error ("stack is empty");
return *array [count - 1U];
}
87
Função membro Accept da Classe
StackAsArray
// pgm06_05.cpp
void StackAsArray::Accept (Visitor& visitor) const
{
for(unsigned int i = 0; i < count && !visitor.IsDone(); ++i)
{
visitor.Visit (*array [i]);
}
}
88
Funções membro da Classe
StackAsArray::Iter
Na definição da classe StackAsArray foi definida uma classe
embutida Iter
A classe StackAsArray::Iter é uma classe friend da classe
StackAsArray tendo acesso às variáveis membro e funções
privados daquela classe
A implementação do iterator depende da implementação do
container
89
Funções membro da Classe
StackAsArray::Iter (1)
// pgm06_06.cpp
StackAsArray::Iter::Iter (StackAsArray const& _stack) :
stack (_stack)
{ Reset (); }
bool StackAsArray::Iter::IsDone () const
{ return position >= stack.count; }
Object& StackAsArray::Iter::operator * () const
{
if(position < stack.count)
return *stack.array [position];
else
return NullObject::Instance ();
}
90
Funções membro da Classe
StackAsArray::Iter (2)
// pgm06_06.cpp (ContinuaçÃo)
void StackAsArray::Iter::operator ++ ()
{
if(position < stack.count)
++position;
}
void StackAsArray::Iter::Reset ()
{ position = 0; }
91
Exemplo de uso de Iterator
Considere-se o código que se segue
StackAsArray stack;
stack.Push (*new Int (3));
stack.Push (*new Int (1));
stack.Push (*new Int (4));
Iterator& i = stack.NewIterator ();
while (!i.IsDone ()) {
cout << *i << endl;
++i;
}
delete &i;
92
Exemplo de uso de Iterator
Este código declara uma variável stack
Diversos objetos do tipo Integer são empilhados.
Finalmente um Iterator é usado para imprimir de maneira
sistemática todos os objetos na pilha.
93
Pilhas Implementadas em C++
Utilizando Listas Encadeadas
Definição da Classe
StackAsLinkedList
//
pgm06_07.cpp
class StackAsLinkedList : public Stack {
LinkedList<Object*> list;
class Iter;
public:
StackAsLinkedList ();
// ...
friend class Iter;
};
class StackAsLinkedList::Iter : public Iterator {
StackAsLinkedList const& stack;
ListElement<Object*> const* position;
public:
Iter (StackAsLinkedList const&);
// ...
};
95
Funções membro Construtor,
Destrutor e Purge da Classe
StackAsLinkedList
//
pgm06_08.cpp
StackAsLinkedList::StackAsLinkedList () :
list ()
{}
void StackAsLinkedList::Purge ()
{
if(IsOwner()) {
ListElement<Object*> const* ptr;
for (ptr = list.Head (); ptr != 0; ptr = ptr->Next ())
delete ptr->Datum ();
}
list.Purge ();
count = 0;
}
StackAsLinkedList::~StackAsLinkedList ()
96
{ Purge (); }
Funções membro Push, Pop e Top da
Classe StackAsLinkedList (1)
// pgm06_09.cpp
void StackAsLinkedList::Push (Object& object)
{
list.Prepend (&object);
++count;
}
Object& StackAsLinkedList::Pop ()
{
if(count == 0)
throw domain_error ("stack is empty");
Object& const result = *list.First ();
list.Extract (&result);
--count;
return result;
}
97
Funções membro Push, Pop e Top da
Classe StackAsLinkedList (2)
// pgm06_09.cpp (Continuação)
Object& StackAsLinkedList::Top () const
{
if(count == 0)
throw domain_error ("stack is empty");
return *list.First ();
}
98
Função membro Accept da Classe
StackAsLinkedList
// pgm06_10.cpp
void StackAsLinkedList::Accept (Visitor& visitor) const
{
ListElement<Object*> const* ptr;
for(ptr = list.Head ();ptr != 0 && !visitor.IsDone ();
ptr = ptr->Next ())
{
visitor.Visit (*ptr->Datum ());
}
}
99
Funções membro da Classe
StackAsLinkedList::Iter (1)
// pgm06_11.cpp
StackAsLinkedList::Iter::Iter (
StackAsLinkedList const& _stack) :
stack (_stack)
{ Reset (); }
bool StackAsLinkedList::Iter::IsDone () const
{ return position == 0; }
Object& StackAsLinkedList::Iter::operator * () const
{
if(position != 0)
return *position->Datum ();
else
return NullObject::Instance ();
}
100
Funções membro da Classe
StackAsLinkedList::Iter (2)
// pgm06_11.cpp (Continuação)
void StackAsLinkedList::Iter::operator ++ ()
{
if(position != 0)
position = position->Next ();
}
void StackAsLinkedList::Iter::Reset ()
{ position = stack.list.Head (); }
101
Filas
Filas Implementadas em C++
Utilizando Arrays
Definição da Classe Queue
//
pgm06_13.cpp
class Queue
{
public:
virtual
virtual
virtual
};
: public virtual Container
Object& Head () const = 0;
void Enqueue (Object&) = 0;
Object& Dequeue () = 0;
104
Definição da Classe QueueAsArray
//
pgm06_14.cpp
class QueueAsArray : public virtual Queue
{
protected:
Array<Object*> array;
unsigned int head;
unsigned int tail;
public:
QueueAsArray (unsigned int);
~QueueAsArray ();
// ...
};
105
Funções membro Construtor,
Destrutor e Purge da Classe
QueueAsArray (1)
// pgm06_15.cpp
QueueAsArray::QueueAsArray (unsigned int size) :
array (size),
head (0),
tail (size - 1U)
{}
106
Funções membro Construtor,
Destrutor e Purge da Classe
QueueAsArray (2)
// pgm06_15.cpp (Continuação)
void QueueAsArray::Purge ()
{
if(IsOwner ())
{
for(unsigned int i = 0; i < count; ++i)
{
delete array [head];
if(++head == array.Length ())
head = 0;
}
}
count = 0;
}
QueueAsArray::~QueueAsArray ()
{ Purge (); }
107
Funções membro Head, Enqueue e
Dequeue da Classe QueueAsArray (1)
// pgm06_16.cpp
Object& QueueAsArray::Head () const
{
if(count == 0)
throw domain_error ("queue is empty");
return *array [head];
}
void QueueAsArray::Enqueue (Object& object)
{
if(count == array.Length ())
throw domain_error ("queue is full");
if(++tail == array.Length ())
tail = 0;
array [tail] = &object;
++count;
}
108
Funções membro Head, Enqueue e
Dequeue da Classe QueueAsArray (2)
// pgm06_16.cpp (Continuação)
Object& QueueAsArray::Dequeue ()
{
if (count == 0)
throw domain_error ("queue is empty");
Object& result = *array [head];
if (++head == array.Length ())
head = 0;
--count;
return result;
}
109
Filas Implementadas em C++
Utilizando Listas Encadeadas
Definição da Classe
QueueAsLinkedList
//
pgm06_17.cpp
class QueueAsLinkedList : public virtual Queue
{
protected:
LinkedList<Object*> list;
public:
QueueAsLinkedList ();
~QueueAsLinkedList ();
// ...
};
111
Funções membro Construtor,
Destrutor e Purge da Classe
QueueAsLinkedList
//
pgm06_18.cpp
QueueAsLinkedList::QueueAsLinkedList () :
list ()
{}
void QueueAsLinkedList::Purge () {
if(IsOwner ()) {
ListElement<Object*> const* ptr;
for(ptr = list.Head (); ptr != 0; ptr = ptr->Next ())
delete ptr->Datum ();
}
list.Purge ();
count = 0;
}
QueueAsLinkedList::~QueueAsLinkedList ()
{ Purge (); }
112
Funções membro Head, Enqueue e
Dequeue da Classe
QueueAsLinkedList (1)
// pgm06_19.cpp
Object& QueueAsLinkedList::Head () const
{
if (count == 0)
throw domain_error ("queue is empty");
return *list.First ();
}
void QueueAsLinkedList::Enqueue (Object& object)
{
list.Append (&object);
++count;
}
113
Funções membro Head, Enqueue e
Dequeue da Classe
QueueAsLinkedList (2)
// pgm06_19.cpp (Continuação)
Object& QueueAsLinkedList::Dequeue ()
{
if(count == 0)
throw domain_error ("queue is empty");
Object& result = *list.First ();
list.Extract (&result);
--count;
return result;
}
114