Sei sulla pagina 1di 8

Estruturas de Dados I

Copywrite 2011-2013 by LCDG


/** Est vazia? */
public boolean isEmpty() { return top == -1; }
/** Est cheia? */
public boolean isFull()

{ return top == list.length - 1; }

/** Representao da pilha como string */


@Override
public String toString() {
if (isEmpty())
return "[]";
String s =
for (int i
s += ",
return s +

"[" + list[0];
= 1; i <= top; i++)
" + list[i];
"]";

}
} // Stack

Ao final da classe acrescentam-se tambm as excees utilizadas


...
@SuppressWarnings("serial")
class StackUnderflowException extends RuntimeException {
public StackUnderflowException(String message) {
super(message);
}
}
@SuppressWarnings("serial")
class StackOverflowException extends RuntimeException {
public StackOverflowException() {
super("Sem pushes numa pilha cheia.");
}
}

2.2.2 Implementaes mais flexveis de estruturas baseadas em arrays


Numa implementao mais flexvel para containers internos de tipo array, pode-se instanciar um objeto
utilizando-se tanto um construtor sem parmetros como construtores com parmetros.
Caso o objeto seja construdo sem parmetros, pode-se assumir de modo ad-hoc uma capacidade inicial
default (por exemplo, 4 floats). Assim, o tipo permite a sua modificao com a demanda: por exemplo, caso
esgote-se a capacidade, um novo array com o 2 vezes o tamanho original alocado (mantendo os
elementos anteriormente contidos que so obviamente copiados); caso container tenha a sua capacidade
menor que do array, aloca-se um novo array com a metade da capacidade atual (e igualmente feita a
bvia cpia dos elementos do antigo). Esses valores 2 e foram adaptados de uma ideia do livro do
Tenenbaum. Os autores apresentam como algoritmo os nmeros 2 e , algo que deve degradar a
performance caso pushes e pops sejam efetuados prximos a 100% da capacidade. Ou seja, a performance
ser degradadada pela alocao/cpia de massas de dados entre arrays. Os nmeros 2 e foram
escolhidos porque o overhead dos testes que sero mostrados nas chamadas de push e pop podem ser
minimizados: multiplicaes e divs por potncias de 2 so operaes rpidas de CPU e talvez as mais
simples numa primeira implementao (em princpio, o compilador otimiza o cdigo atravs de bitshifts
direita e esquerda para implementar div e mod). A API do Java faz uma implementao que adiciona um
tamanho fixo capacidade.
Vamos definir tambm que um array com capacidade mnima sempre alocado. Essa capacidade mnima
ser um atributo do tipo e no do objeto: uma constante MINCAPACITY que ser definida por convenincia
de manuteno do tipo.
Vamos ento redefinio do tipo que comporte essas mudanas.

10/35

Estruturas de Dados I
Copywrite 2011-2013 by LCDG
/**
* Criao de uma pilha, inicialmente vazia, capaz de armazenar floats.
* Pode ser especificada uma capacidade inicial n ou no, e o espao
* automaticamente redimensionado automaticamente, por cada push e pop.
* O default (MINCAPACITY) uma capacidade para 4 floats.
* Construtores:
*
public Stack(int n);
*
Prcondio: n >= 0. Para n < MINCAPACITY, n = MINCAPACITY.
*
public Stack();
*
Prcondio: nenhuma.
*/
public abstract class AbstractStack1 {
...
public abstract void push(float item);
...
public abstract float pop();
...
public abstract float peek();
...
public abstract boolean isEmpty();
...
public abstract String toString();
}

Os dois construtores que fornecero algum conforto so


public class Stack extends AbstractStack {
private static final int MINCAPACITY = 4;
private final int OCAPACITY; // Capacidade original da pilha
private float[] list;
private int top;

// Array onde a pilha est


// top aponta para o topo da pilha

public Stack(int n)
{
if (n < 0)
throw new IllegalArgumentException("Tamanho invlido: " + n);
if (n < MINCAPACITY) n = MINCAPACITY;
list = new float[n];
// Cria o array com n posies
top = -1;
// -1 indica pilha vazia
OCAPACITY = n;
// Salva o valor original de list.length
}
public Stack() {
this(MINCAPACITY);
}
...

// Pilha de tamanho inicial MINCAPACITY

Duas observaes. Primeira: MINCAPACITY um atributo privado (o usurio no pode zoar com ele),
esttico (ou seja, uma caracterstica do tipo e no da instncia) e final (uma vez associado um valor a ele,
no poder mais ser alterado em ponto algum do cdigo). uma constante de tipo e vale para todas as
instncias criadas (sem exceo). Segunda: caso o usurio fornea uma capacidade menor que
MINCAPACITY, o tipo ( revelia) cria uma pilha com capacidade inicial MINCAPACITY. No seremos chatos
com o usurio e abortar o cdigo s porque ele no leu direito o manual (que ainda no est feito) e iniciaremos
com a capacidade default.
Eram duas observaes? No. So 3. OCAPACITY um atributo privado (o usurio no pode zoar com ele),
NO esttico (ou seja, uma caracterstica da instncia e no do tipo) e final (uma vez associado um valor a
ele, no poder mais ser alterado em ponto algum do cdigo). uma constante de instncia e vale apenas
para a particular instncia. (Foi um copy & paste do pargrafo anterior? )
De modo assim at random, vamos agora escrever umas operaes auxiliares que sero teis

11/35

Estruturas de Dados I
Copywrite 2011-2013 by LCDG
...
// Mtodo auxiliar para modificar o tamanho do array list
private void resize(int newSize) {
// n tem a menor capacidade e no trunca a pilha ?
assert newSize >= OCAPACITY && newSize > top;
// Copia os antigos valores para a nova pilha
float[] newList = new float[newSize];
for (int ndx = 0; ndx <= top; ndx++)
newList[ndx] = list[ndx];
list = newList;
}
/** Est vazia? */
public boolean isEmpty() { return top == -1; }
/** Est cheia? */
private boolean isFull() { return top == list.length - 1; }
...

resize() muda o tamanho do array fazendo a cpia do que antes estava l (at top, inclusive). A assero
colocada indica que sempre que resize(n) chamado, n consistido caso o compilador tenha as
verificaes de asseres habilitadas (o default que no se verifiquem). Alm de documentar o cdigo, a
assero algo til em cdigos maiores numa fase de depurao. isFull() agora passa a ser um mtodo
privado, j que o usurio no mais necessita fazer esse teste (mas continua sendo feito no corpo de Stack).
Terreno preparado agora, pode-se finalmente escrever push() e pop()
...
/**
* Adiciona item na pilha.<br>
* @param value o valor que colocado na pilha
* @exception OverflowException no caso da pilha estar cheia
*/
public void push(float item) {
if (isFull())
resize(2 * list.length);
list[++top] = item;
// Coloca no final da lista
}
/**
* Remove do topo da pilha e retorna valor.<br>
* @return o valor do topo da pilha.
* @exception UnderflowException no caso da pilha estar vazia
*/
public float pop() {
if (isEmpty())
// ... se vazia gera exceo
throw new UnderflowException("Sem pops numa pilha vazia.");
/* No caso da lista ficar ocupada e o tamanho ainda ser
maior que OCAPACITY, divide o tamanho por 2*/
if (top < list.length / 4 && list.length > OCAPACITY)
resize(list.length / 2);
return list[top--];
// Retorna o topo e decr. top
}
...

Conforme prometido, isFull() agora apenas utilizada por propsitos de legibilidade do cdigo. De
acordo com o fato da pilha estar cheia, push() incumbe-se de aumentar o tamanho do array antigo,
mantendo os valores l anteriormente (note que a pilha mantm-se inalterada e top no deve ser alterado
por resize(), como no ). No caso de pop(), caso o array esteja meio vazio (digo, com menos de
da capacidade preenchida), diminui-se o espao que ele ocupa.
Os mtodos restantes, peek() e toString() permanecem inalterados da implementao 1.
Note que agora push() e pop() no so mais O(1)! Como as operaes de redimensionamento do array no
so frequentes diz-se que push() e pop() tem complexidade O(1) amortizada. Ou seja, O(1) na maior parte
do tempo e as eventuais operaes O(n) so diludas em mdia pela maior ocorrncia de operaes O(1).
Nessa verso que ajusta o tamanho dos arrays, note tambm que existe um preo a pagar pela

12/35

Estruturas de Dados I
Copywrite 2011-2013 by LCDG
flexibilidade: a do overhead pequeno (mas que existe) a cada push() e pop(), devido aos testes adicionais
efetuados.

2.3 Exerccios tericos (usar lpis, papel e a cabea. E no o teclado +

compilador)

1. (a.2013) Exemplifique algumas aplicaes que possam ser feitas com pilhas alm das discutidas em
sala de aula.

2. (a.2013) Explique as condies de estouro da pilha (overflow e underflow) atravs de exemplos.


3. (Sedgewick, a.2012) [] O que faz o fragmento de cdigo abaixo quando n = 500?
Stack stack = new Stack();
while (n > 0) {
stack.push(n % 2);
n = n / 2;
}
while (!stack.isEmpty())
System.out.print(stack.pop());
System.out.println();

4. (UW's CSE142, a.2013) Suponha que foi pedida a escrita de um mtodo max o qual aceita como

parmetro uma pilha de inteiros e que retorna o maior inteiro contido na pilha. Algum fez a codificao
como se segue, preocupando-se admiravelmente em citar a precondio de que a pilha no esteja vazia
para que o cdigo funcione:
//Precondio: !s.isEmpty()
public static void max(Stack s) {
int maxValue = s.pop();
while (!s.isEmpty()) {
int popped = s.pop();
if (maxValue < popped)
maxValue = popped;
}
return maxValue;
}

O cdigo foi testado e apresentou problemas mesmo com pilhas passadas no vazias? Qual o problema
desse cdigo?

5. (Sedgewick, a.2012) [] Suponha que operaes de push() e pop() so efetuadas ao acaso em uma pilha.

As operaes de push() colocam inteiros em ordem estritamente crescente na pilha (ou seja, uma vez que
o usurio coloca um nmero na pilha, o prximo dever ser maior). A cada pop() efetuado, o valor removido
da pilha impresso. Qual das sadas abaixo no pode ocorrer?
(a) 4 3 2 1 0 9 8 7 6 5
(b) 4 6 8 7 5 3 2 9 0 1
(c) 2 5 6 7 4 8 9 3 1 0
(d) 4 3 2 1 0 5 6 7 8 9
(e) 1 2 3 4 5 6 9 8 7 0
(f) 0 4 6 5 3 8 1 7 2 9
(g) 1 4 7 9 8 6 5 3 0 2
(h) 2 1 4 3 6 5 8 7 9 0

Infixa, psfixa e afins


6. a.2013) Exemplifique algumas aplicaes que possam ser feitas com pilhas alm das discutidas em sala
de aula.

13/35

Estruturas de Dados I
Copywrite 2011-2013 by LCDG

7. (a.2013) [Explique o que so expresses prefixadas, infixas, e psfixadas. D um exemplo para cada (2 ou
3 operaes, ilustrando a precedncia, etc.).

8. (a.2013) [ Escreva as expresses abaixo da notao infixa para a psfixa (^ o operador expoente que tem
precedncia maior que os demais. a^b o mesmo que ab)
(x + y z)/(h + k)*s, j k/g^h + (n + m) e a*(b c)/d + e*f

9. (Preiss, a.2012) [] Escreva as expresses infixas abaixo na notao prefixada


(a) a+b*c/d
(b) a+b*(c/d)
(c) (a+b)*c/d
(d) (a+b)*(c/d)
(e) (a+b*c)/d
10. (Preiss, a.2012) [] Escreva as expresses abaixo, da forma posfixa, em infixa:
(a) w x y / x *
(b) w x y z * /
(c) w x y / z *
(d) w x y z * /
(e) w x y / - z *
(f) y z * w x /
11. (a.2013) Calcule o valor final de cada uma das expresses psfixas abaixo, para os dados fornecidos:
(a) ab^c*d/e + onde a = 5, b = 3, c = d = 2, e = 9
(b) abcde+* + onde a = 12, b = 4, c = 7, d = 5, e = 2
(c) ab + cd* + e* onde a = 2, b = 6, c = 3, d = 5, e = 9
2.4 Usando a pilha (ou seja, no modificaremos a classe)
Para os exerccios dessa seo, o usurio tem apenas acesso ao tipo montado e compilado. Os cdigos
devem ser escritos sem a tentativa de modificar o tipo.

12. (a.2013) Enunciado curto: Escreva um cdigo caprichado com um menuzinho que mostre as
operaes de pilha para um usurio.
Enunciado extenso (no sei como fazer algo pedido como um enunciado to vago como o
anterior): Escreva o cdigo com um menuzinho que mostre as operaes de pilha para um usurio (cria
pilha com tal tamanho, empilha nmero, desempilha e mostra o que desempilhou, quando inserir um
nmero ou o cdigo gera um nmero ou pede um nmero ao usurio, etc., etc.). O estado da pilha sempre
deve ser mostrado e, obviamente, no deve haver estouros durante a execuo do cdigo.

13. (Sedgewick, a.2012) [] Escreva um trecho de programa que leia caracteres da entrada e que os
imprima em ordem reversa. Use uma pilha. Nada de contadores.

14. (Sedgewick, a.2012) [] Escreva um trecho de programa que leia um nmero indeterminado de doubles
positivos da entrada (a sequencia pode terminar em 0 ou em um double negativo). Em seguida criado um
array com o tamanho exato do nmero de doubles entrados. O array de doubles inicializado com os
doubles lidos na ordem reversa quela da leitura. Use uma pilha. Nada de contadores.

14/35

Estruturas de Dados I
Copywrite 2011-2013 by LCDG

15. (Preiss, a.2012) [] Escreva um algoritmo que traduza da notao psfixa para a prefixa.

Ex: w x y / z * / w x * y z.
w x y / - z * * - w / x y z
Sugesto (quase a soluo) que usa concatenao de strings e uma pilha: Letra lida empilhada.
Operador lido: dois caracteres da pilha de letras so popados, concatenados com o operador lido e
colocados de volta na pilha. Ou seja, a pilha de strings. Ao final da leitura da string de entrada, a pilha deve
conter apenas um elemento. Else, houve erro na expresso de entrada. Faz a bem feitinho, escrevendo
inicialmente para algo correto e adicionando os casos de expresso vazia e expresses erradas. Bem bacana
esse exerccio.

16. (Preiss, a.2012) [] Implemente uma fila utilizando duas pilhas. Fornea os algoritmos para enqueue e
dequeue. Quanto seria o O() para essa implementao?
Sugesto A (quase a soluo): Toda vez que ocorre um enqueue(), um dado pushado numa pilha A. Toda
a vez que ocorre um dequeue(), os dados existentes so invertidos pushando eles numa pilha B e retornado
e removido o ltimo pushado. Os dados so ento retornados pilha A. Note: enqueue() O(1) e dequeue()
O(2n).
Sugesto B (quase a soluo): Toda vez que ocorre um dequeue(), um dado popado numa pilha A. Toda
a vez que ocorre um enqueue(), os dados existentes so invertidos pushando eles numa pilha B, e inserido o
novo dado. Os dados so ento retornados pilha A. Note: dequeue() O(1) e enqueue() O(2n).
Sugesto C (quase a soluo): Ganha um brinde se fizer com o melhor mtodo. Existe a necessidade de se
manter um apontador para uma pilha corrente e tomar umas decises. Pense nas sugestes anteriores.
17. (LCDG, 2011, a.2012) [] Suponha duas pilhas. Uma pilha A inicialmente vazia e outra pilha B que ser

montada com objetos sua escolha (4 nmeros ou 10 letras, por exemplo). Monte main() de modo a que
a pilha B seja impressa NA ORDEM EM QUE OS ELEMENTOS ENTRARAM NELA e que
a pilha B volte ao estado inicial aps a impresso
RESPONDA COM UM CDIGO FEITO EM JAVA E TESTADO.

18. (LCDG, 2011, a.2012) [] Para uma implementao diferente de pilha, os itens so dispostos ao
contrrio no array, conforme a figura abaixo. Ou seja, a pilha cresce do ndice maior para o menor no
array. O ndice do topo dado por myTop. Suponha tambm que o array foi instanciado com tamanho 6
para resolver os itens de a) a e). Nada de implementar. Faa mo.
public class Stack {
private float[] myArray;
private int myTop;
// mais nenhum atributo
...
// o resto da classe est aqui
};

?
1

40,2

3,1

6,4

4,2

myTop

(a) Qual valor ter myTop quando a pilha estiver vazia? _____
(b) Qual valor ter myTop quando a pilha estiver cheia? _____
(c) Quantos itens a pilha acomoda? _____
(d) Qual valor ser o primeiro valor a ser removido da pilha da figura?_____
(e) Qual valor seria o ltimo valor a ser removido da pilha da figura?_____
(f) Codifique int push(float item), que insere um float na pilha. disposio existe boolean isFull()
para testar se a pilha est cheia. push()retorna o nmero de elementos que a pilha contm aps a
insero de item (no existe o mtodo lenght()). Caso haja erro, push() retorna o nmero mximo de
elementos que a pilha contm somado com 1.

15/35

Estruturas de Dados I
Copywrite 2011-2013 by LCDG

(g) Codifique void sumTwo(). Esse mtodo retorna a soma dos dois elementos mais ao topo, que devem
ser removidos da pilha, e a soma colocada no topo. Note: No necessrio fazer a verificao de
pilha vazia. pop() no foi implementado e no perca seu tempo com a implementao dele.
(h) Codifique o construtor.

19. (Classic, a.2013) Escreva um mtodo de testes

public static void reverse(Stack s)


que inverte a ordem dos elementos em uma pilha s. Por exemplo, reverse(s) transforma s: [1, 2, 3] em
s: [3, 2, 1], s: [ ] em [ ] e null em null. Nada de contadores.
A trensferncia de uma pilha para uma pilha temporria inverte s. Da temporria para uma segunda
temporria faz com que s volte ao seu formato inicial. Dessa ltima para s, finalmente, faz com que s fique
invertida. Ficaria
public class StackExerciseReverse {
public static void reverse(Stack s) {
// Nada faz com no objetos
if (s == null)
return;

Stack stmp1 = new Stack(),


stmp2 = new Stack();
// Passo 1: Esvazio s e preencho stmp1
while (!s.isEmpty())
stmp1.push(s.pop());
// Passo 2: Esvazio stmp1 e preencho stmp2
while (!stmp1.isEmpty())
stmp2.push(stmp1.pop());
// Passo 3: Esvazio stmp2 e preencho s
while (!stmp2.isEmpty())
s.push(stmp2.pop());

public static void main(String[] args) {


// Cria pilha com [1, 2, 3]
Stack s = new Stack();
for (int i = 3; i >= 1; --i)
s.push(i);
System.out.println("Pilha:" + s);
reverse(s);
System.out.println("Pilha aps reverse:" + s);
}

Verifique que reverse() funciona mesmo quando s vazia.

20. (Inspirado por UW's CSE142, a.2013) Escreva um mtodo de testes

public static void stutter(Stack s)


que duplica os elementos em uma pilha s, mentendo a sua ordem anterior. Por exemplo, stutter(s)
transforma s: [1, 2, 3] em s: [1, 1, 2, 2, 3, 3], s: [ ] em [ ] e null em null. Nada de contadores.

21. (Inspirado por UW's CSE142, a.2013) Escreva um mtodo de testes

public static void mirror(Stack s)


que espelha os elementos em uma pilha s. Por exemplo, mirror(s) transforma s: [1, 2, 3] em
s: [1, 2, 3, 3, 2, 1], s: [ ] em [ ] e null em null. Nada de contadores.

22. (a.2013) Escreva um programa que determina se uma string consiste de um nmero de caracteres A
seguidos do mesmo nmero de caracteres 'B'. Use uma pilha. Nada de contadores.

16/35

Estruturas de Dados I
Copywrite 2011-2013 by LCDG

23. (UFOP, a.2012) [] Escreva um mtodo que determine se uma string da forma s = wCwR, onde w

uma string e wR a string reversa de w, sendo que w contm apenas os caracteres A e B. Por exemplo,
para w= ABABBA, s = ABABBACABBABA. Mandatoriamente, a string s lida da esquerda para a
direita apenas, caracter a caracter. Utilize uma pilha. Nada de contadores.

24. (UFOP, a.2012) [] Escreva um mtodo que determine se uma string da forma

s = w1Dw1RDw2Dw2RDw3Dw3R... wnDwnR
onde cada wj uma string e wjR a string reversa de wj, sendo que wj contm apenas os caracteres A e B.
Mandatoriamente, a string s lida da esquerda para a direita apenas, caracter a caracter. Utilize uma pilha.
Nada de contadores.

25. (UFOP, a.2012) [] Considere uma pilha P vazia e uma fila F no vazia, ambas sendo containers do

mesmo tipo (char, por exemplo). Utilizando apenas os predicados isEmpty(), as operaes enqueue(),
dequeue(), push(), e uma varivel auxiliar aux do mesmo tipo que F e P contm, escreva um mtodo que
inverta a ordem dos elementos da fila. Nada de contadores.

26. (CCSU,Java Au Naturel, a.2012) [] Escreva um mtodo de testes

public static void transfer(Stack s1, Stack s2)


que transfere os elementos de s1 para s2. Os elementos eventualmente antes em s2 so descartados. A
pilha s2 passa a ter uma cpia da pilha s1 e s1 torna-se vazia. Restrio: Use apenas uma terceira pilha
temporria. Nada de contadores.

27. (CCSU,Java Au Naturel, a.2012) [] Escreva um mtodo de testes

public static void swapStacks(Stack s1, Stack s2)


Os contedos das duas pilhas so trocados. Ou seja, o que estava em s1 passa para s2 e vice-versa.
As pilhas ficam na ordem original. Restrio: Apenas uma pilha adicional pode ser utilizada. Nada de
contadores.

28. (CCSU,Java Au Naturel, a.2012) [] Escreva um mtodo de testes

public static void removeDownTo(Stack s, Object obj)


Todos os valores da pilha s, at o valor que obj seja encontrado mas excluindo-se ele, so removidos. Se
nenhum for igual a obj, a pilha s resultar em vazia. Lembrar que obj pode ser null. Nada de contadores.

29. (CCSU,Java Au Naturel, a.2012) [] Escreva o mtodo avulso

public static Object removeSecond(Stack s)


Esse mtodo remove e retorna o elemento imediatamente abaixo do topo da pilha, no caso da pilha ter ao
menos 2 objetos. Caso contrrio, simplesmente retorna null e a pilha stack deve permanecer inalterada.
Nada de contadores.

2.5 Reescrevendo a classe (ou estendendo, voc decide)


30. (a.2013) Adicione a operao

public int size()


ao tipo Stack, que informa o nmero de itens presentes na pilha.

31. (a.2013) Adicione a operao

public int capacity()


ao tipo Stack, que informa o nmero de mximo de itens que a pilha comporta.

32. (a.2013) [null] Adicione a operao

17/35

Potrebbero piacerti anche