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)
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
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
Uma operação adicional sobre pilhas é a verificação do elemento no topo da pilha getTop.
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
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.
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
A formulação espontânea contém dois ponteiros frente e retaguarda ou head e tail
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
O ajustamento de ponteiros por ocasião de inclusões e exclusões se torna diferente
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
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
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
public 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);
}
// pgm05_02.java
// pgm05_02.java
public abstract class AbstractObject implements Comparable
Este código cria uma instância da classe StackAsArray e a atribui à variável stack.
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.
Uma classe interior é uma classe definida dentro de outra.
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.
// pgm06_06.java
// 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++];
}
};
}
}
// pgm06_07.java
// pgm06_07.java
public class StackAsLinkedList
extends AbstractContainer
implements Stack
{
protected LinkedList list;
// ...
}
// pgm06_08.java
// 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;
}
// ...
}
// pgm06_09.java
// pgm06_09.java
public class StackAsLinkedList
extends AbstractContainer
implements Stack
{
protected LinkedList list;
public void push (Object object)
{
list.prepend (object);
++count;
}
// pgm06_09.java (Continuação)
// 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 ();
}
// ...
}
// pgm06_10.java
// 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;
}
}
// ...
}
// pgm06_11.java
// pgm06_11.java
public class StackAsLinkedList
extends AbstractContainer
implements Stack
{
protected LinkedList list;
// pgm06_11.java (Continuação)
// pgm06_11.java (Continuação)
public Enumeration getEnumeration () {
return new Enumeration () {
protected LinkedList.Element position =list.getHead();