SlideShare ist ein Scribd-Unternehmen logo
1 von 9
Downloaden Sie, um offline zu lesen
Alocação seqüencial - pilhas
Mac122 – Marcilio

Alocação sequencial - Pilhas
Pilhas
A estrutura de dados Pilha é bastante intuitiva. A analogia é uma pilha de pratos. Se
quisermos usar uma pilha de pratos com a máxima segurança, devemos inserir um novo
prato “no topo” da pilha e retirar um novo prato “do topo” da pilha.
Por isso dizemos que uma pilha é caracterizada pelas seguintes operações:
O último a entrar é o primeiro a sair ou
O primeiro a entrar é o último a sair
Os nomes usados em inglês são:
LIFO – last in first out ou
FILO – first in last out
Considere o exemplo abaixo que mostra a evolução de uma pilha.
 Uma letra significa empilhe a letra;
 Um ponto significa desempilhe uma letra;
operação
E
X
E
.
.
M
P
.
.
.
L
O
.
D
E
P
I
.
.
.
.
.
.
L

retirado

E
X
L
P
M
E

O

I
P
E
D
L

Alocação seqüencial - pilhas
Mac122 – Marcilio

Pilha
E
EX
EXE
EX
E
EM
EMP
EM
E
L
LO
L
LD
LDE
LDEP
LDEPI
LDEP
LDE
LD
L
Erro – pilha vazia
L
Alocação seqüencial - pilhas
Mac122 – Marcilio

H
A

LH
LHA

A implementação de uma pilha num vetor de inteiros ficaria:
int pilha[MAX]; /* pilha[0] ... pilha[MAX-1] */
int topo;
/* indica elemento de cima da pilha */
/* inicia pilha */
void inicia_pilha () {
topo = -1;
}
/* empilha novo elemento */
int empilha(int x) {
if (topo == MAX-1) return -1; /* não há mais espaço */
topo++;
pilha[topo] = x;
return 0;
}
/* desempilha novo elemento */
int desempilha(int *x) {
if (topo < 0) return -1; /* pilha vazia */
*x = pilha[topo];
topo--;
return 0;
}
Usamos acima uma pilha de inteiros (int), mas poderíamos usar as mesmas funções com
uma pilha de elementos de qualquer um dos tipos básicos (char, float, double, etc.).
Não haveria mudança mesmo se a pilha fosse de elementos do tipo struct. Veja abaixo:
/* cada um dos elementos da pilha */
struct elemento {
...
}
struct elemento pilha[MAX];
int topo;
/* inicia pilha */
void inicia_pilha () {
topo = -1;
}
/* empilha novo elemento */
Alocação seqüencial - pilhas
Mac122 – Marcilio
Alocação seqüencial - pilhas
Mac122 – Marcilio

int empilha(struct elemento x) {
if (topo == MAX-1) return -1; /* não há mais espaço */
topo++;
pilha[topo] = x;
return 0;
}
/* desempilha novo elemento */
int desempilha(struct elemento *x) {
if (topo < 0) return -1; /* pilha vazia */
*x = pilha[topo];
topo--;
return 0;
}
Aplicações
A estrutura de pilha é uma estrutura fundamental em muitas aplicações da computação.
Citamos alguns:
a) Na execução de um programa, quando se entra num novo bloco, podem existir novas
variáveis. Estas novas variáveis são alocadas numa pilha de variáveis, pois na saída do
bloco o espaço ocupado deve ser liberado para dar lugar a novas variáveis quando a
execução entrar em novos blocos.
A
b
{int a,b;
.......
a
b
x
y
x
{int x,y,z;
.......
a
b
x
y
X
{ int b, k;
.....
a
b
x
y
x
}
........
}
a
b
........
}

b

k

b) A tabela de símbolos de um compilador, onde ficam as variáveis declaradas tem uma
estrutura de pilha. Note que variáveis podem ter o mesmo nome em blocos diferentes e usase sempre a que foi declarada por último. Assim a busca na tabela de símbolos deve ser
feita sempre do fim para o começo. Além disso, quando termina um bloco onde há
variáveis locais, estas desaparecem da tabela de símbolos.
c) O próprio algoritmo de análise sintática (aquele algoritmo que verifica se a sintaxe do
programa está correta) usa uma pilha sintática, para guardar o contexto do programa sendo
Alocação seqüencial - pilhas
Mac122 – Marcilio
Alocação seqüencial - pilhas
Mac122 – Marcilio

analisado (para entender melhor isso seria necessário conhecer melhor esses algoritmos, o
que não é objeto deste curso).
d) Suponha que durante a execução de um programa, uma função f, chama uma função g,
que chama uma função h. Obviamente, depois da execução de h, deve-se voltar para g e
depois de g, voltar para f. Os endereços de retorno após a chamada de uma função, são
colocados numa pilha de execução, para que se volte para o lugar certo.
e) Um caso especial é quando usamos funções recursivas. Como a função chamada é
sempre a mesma, o controle dos endereços de retorno e dos parâmetros de cada chamada, é
feito pela pilha de execução. Os parâmetros de cada chamada são também empilhados.
Notação pós-fixa para expressões
A notação pós-fixa para expressões, também chamada de notação polonesa, pois foi
inventada pelo matemático polonês Jan Łukasiewicz (1878 - 1956) e usada pela primeira
vez em computação pelo cientista de computação Charles Hamblin em 1957, apresenta
uma série de facilidades em relação a notação tradicional. Nela os operadores aparecem
após os operandos e não entre os operandos.
Exemplos:
1
2
3
4
5
6
7

Notação usual (in-fixa)
a+b
a+b+c
a+b*c
(a+b)*c
c*(a+b)
b^2-4*a*c
(-b+√( b^2-4*a*c))/(2*a)

Notação polonesa (pós-fixa)
ab+
ab+c+ ou abc++
abc*+
ab+c*
cab+*
B2^4a*c*- ou b2^4ac**b-b2^4ac**-√+2ª*/

Algumas observações sobre a notação pós-fixa:
a) Essa notação elimina a necessidade de parêntesis.
b) Pode existir mais de uma solução (exemplos 2 e 6) devido a mesma prioridade dos
operandos envolvidos. Nos 2 exemplos acima, é melhor considerar a primeira
solução, pois a convenção usual é que quando temos operadores de mesma
prioridade (no exemplo 2 ++ e no exemplo 6 **) as operações são feitas da
esquerda para a direita.
c) Os operandos aparecem na mesma ordem em que se encontram na expressão
original.
d) Podemos usar também os operadores unários. No caso do exemplo 7, usamos os
operadores – (unário) e √ (raiz quadrada). No caso dos operadores unários – e +
que possuem o mesmo símbolo dos binários correspondentes tem que se fazer a
distinção usando outro símbolo para que não haja dúvida sobre a operação.
e) Para se calcular o valor da expressão em notação pós-fixa, varre-se a expressão da
esquerda para a direita simplesmente. Não é necessário verificar qual a operação
que se faz primeiro por que tem mais prioridade ou porque está entre parêntesis.
Alocação seqüencial - pilhas
Mac122 – Marcilio
Alocação seqüencial - pilhas
Mac122 – Marcilio

Algoritmo para transformar uma expressão para a notação pós-fixa
Varrendo a expressão norma da esquerda para a direita, o algoritmo deve levar em conta a
prioridade dos operadores antes de colocá-los na expressão pós-fixa. Assim, antes de
colocar um operador na expressão pós-fixa, é necessário saber se o próximo operador é
menos prioritário que ele.
Isso sugere usar uma pilha para os operadores. Quando chega um operador mais prioritário
que o do topo da pilha, empilha-se este também. Mas se for menos prioritário, o do topo
tem que ir para a expressão pós-fixa e dar lugar para este que acabou de chegar.
Os parêntesis são um caso especial. Quando aparece um fecha, deve-se colocar na pós-fixa
todos os operadores até o abre correspondente.
while (expressão não chegou ao fim) {
pegue próximo elemento p;
if (p é operando) coloque na pós-fixa;
if (p é operador) {
tire da pilha e coloque na pós-fixa todos os operadores
com prioridade maior ou igual a p, na mesma ordem de
retirada da pilha;
empilhe p;
}
if (p é abre parêntesis) empilha p;
if (p é fecha parêntesis)
desempilhe os operadores até o primeiro abre e coloque
na pós-fixa na mesma ordem de retirada da pilha;
}
desempilhe todos os operadores que ainda estão na pilha e
coloque na pós-fixa na mesma ordem de retirada da pilha;
Os operadores devem então estar organizados por sua prioridade.
A função abaixo define a prioridade dos operadores binários +, -, * , /, e ^ .
Para facilitar o algoritmo damos também prioridade ao abre, fecha e a operando, embora
tenham tratamento especial no algoritmo.
int prioridade (char x) {
switch (x) {
case ‘+’: return 1;
case ‘-’: return 1;
case ‘*’: return 2;
case ‘/’: return 2;
case ‘^’: return 3;
case ‘(’: return 4;
case ‘)’: return 5;
default : return 0;
}
Alocação seqüencial - pilhas
Mac122 – Marcilio

/* caso particular */
/* caso particular */
/* é operando */
Alocação seqüencial - pilhas
Mac122 – Marcilio

}

Comportamento da pilha em alguns exemplos
Abaixo, exemplos do comportamento da pilha para algumas expressões:
a+b
Pilha
a
+
b

+
+

Pós-fixa
a
a
ab
ab+

a+b+c
Pilha
a
+
b
+
c

+
+
+
+

Pós-fixa
a
a
ab
ab+
ab+c
ab+c+

a*b+c
Pilha
a
*
b
+
c

*
*
+
+

Pós-fixa
a
a
ab
ab*
ab*c
ab*c+

a+b*c
Pilha
a
+
b
*
c

+
+
+*
+*

a*(b+c)
Pilha
a
*
*
(
*(
Alocação seqüencial - pilhas
Mac122 – Marcilio

Pós-fixa
a
a
ab
ab
abc
abc*+
Pós-fixa
a
a
a
Alocação seqüencial - pilhas
Mac122 – Marcilio

b
+
c
)

*(
*(+
*(+
*

(a+b)*c
Pilha
(
(
a
+
(+
b
(+
)
*
*
c
*
a*(b+(c*(d+e)))
Pilha
a
*
*
(
*(
b
*(
+
*(+
(
*(+(
c
*(+(
*
*(+(*
(
*(+(*(
d
*(+(*(
+
*(+(*(+
e
*(+(*(+
)
*(+(*
)
*(+
)
*
a/(b*c)*d
Pilha
a
/
/
(
/(
b
/(
*
/(*
c
/(*
)
/
*
*
Alocação seqüencial - pilhas
Mac122 – Marcilio

ab
ab
abc
abc+
abc+*
Pós-fixa
a
a
ab
ab+
ab+
ab+c
ab+c*
Pós-fixa
a
a
a
ab
ab
ab
abc
abc
abc
abcd
abcd
abcde
abcde+
abcde+*
abcde+*+
abcde+*+*
Pós-fixa
a
a
a
ab
ab
abc
abc*
abc*/
Alocação seqüencial - pilhas
Mac122 – Marcilio

d

*

abc*/d
abc*/d*

A prioridade dos operadores em C
Nos exemplos acima, usamos os operadores mais usuais, mas todos os operadores em C
tem a sua prioridade associada. Os operadores unários (+ e c-), a atribuição (=), os
operadores lógicos (&& e ||), etc. seguem a mesma regra de cálculo com a sua respectiva
prioridade.
A tabela abaixo mostra os operadores em C com a respectiva prioridade e o mesmo
algoritmo acima pode ser usado para traduzir qualquer expressão ou comando em C.

Prioridade
Operador
() [] . -> ++ -2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Descrição
Direção
Pós
Esquerda-Direita
++ -- ~ ! sizeof new delete
Unários e pré
* &
Ponteiros
Direita-Esquerda
+ Unários
(type)
type casting
Direita-Esquerda
.* ->*
Ponteiros
Esquerda-Direita
* / %
Multiplicativos Esquerda-Direita
+ Aditivos
Esquerda-Direita
<< >>
Shift
Esquerda-Direita
< > <= >=
Relacional
Esquerda-Direita
== !=
Igualdade
Esquerda-Direita
&
Bitwise AND Esquerda-Direita
^
Bitwise XOR Esquerda-Direita
|
Bitwise OR
Esquerda-Direita
&&
Lógico AND Esquerda-Direita
||
Lógico OR
Esquerda-Direita
?:
Condicioanl Esquerda-Direita
= *= /= %= += -= >>= <<= &= ^= |= Atribuição
Direita-Esquerda
,
Vírgula
Esquerda-Direita

Operadores unários e operadores binários
Na notação usual os operadores + e – (adição e subtração) possuem o mesmo símbolo
quando unários ou binários, embora tenham significado diferente. Essa diferença é
resolvida pelos compiladores quando analisam o contexto da expressão.
O ideal seria usar símbolos diferentes para operadores unários e binários.
Alocação seqüencial - pilhas
Mac122 – Marcilio
Alocação seqüencial - pilhas
Mac122 – Marcilio

Algoritmo para o cálculo do valor de uma expressão em notação pós-fixa
Uma vantagem da expressão pós-fixa é que para se calcular o seu valor o algoritmo é mais
simples. Basta varrê-la da esquerda para a direita e efetuar as operações com os dois
últimos operandos, ou o último no caso de operadores unários. Para tanto, os operados tem
que ser empilhados à medida que aparecem, pois a operação será aplicada aos dois últimos
(se for operação binária) ou apenas ao último se for uma operação unária.
while (expressão pós-fixa não chegou ao fim) {
pega próximo elemento p;
if (p é operando) empilha p;
if (p é operador unário) {
faz a operação com o elemento do topo da pilha;
if (p é operador binário) {
faz a operação com os 2 elementos do topo da pilha;
neste caso a pilha diminui de 1 elemento;
}
O resultado da expressão estará no topo da pilha, que ao final se reduz a um único
elemento.
Observe que no algoritmo de tradução, a pilha era de operadores enquanto que no algoritmo
de cálculo a pilha é de operandos.
Exemplo - Considere a expressão aritmética abaixo: e suponha
a=1,b=2,c=3,d=4,e=5:
a*(b+c*(d+e))
que na notação pós-fixa ficaria:
abcde+*+*
Suponha que a=1,b=2,c=3,d=4,e=5. Vamos calcular o valor da expressão já em
notação pós-fixa:
a

1

b

2
1

Alocação seqüencial - pilhas
Mac122 – Marcilio

c

3
2
1

d

e

+

*

+

*

4
3
2
1

5
4
3
2
1

9
3
2
1

27
2
1

29
1

29

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (18)

TDC2018SP | Trilha Ruby - Programacao funcional com Ruby, potencialize e simp...
TDC2018SP | Trilha Ruby - Programacao funcional com Ruby, potencialize e simp...TDC2018SP | Trilha Ruby - Programacao funcional com Ruby, potencialize e simp...
TDC2018SP | Trilha Ruby - Programacao funcional com Ruby, potencialize e simp...
 
Aula14
Aula14Aula14
Aula14
 
Programação funcional
Programação funcionalProgramação funcional
Programação funcional
 
Programação funcional no dia a dia
Programação funcional no dia a diaProgramação funcional no dia a dia
Programação funcional no dia a dia
 
Programação funcional
Programação funcionalProgramação funcional
Programação funcional
 
Conjunto de instruções mips - introdução
Conjunto de instruções mips - introduçãoConjunto de instruções mips - introdução
Conjunto de instruções mips - introdução
 
Tradutor de Pig Latin
Tradutor de Pig LatinTradutor de Pig Latin
Tradutor de Pig Latin
 
Mini R
Mini R Mini R
Mini R
 
Functional Python
Functional PythonFunctional Python
Functional Python
 
Introdução ao R
Introdução ao RIntrodução ao R
Introdução ao R
 
Linguagem R
Linguagem RLinguagem R
Linguagem R
 
Algoritmos
AlgoritmosAlgoritmos
Algoritmos
 
Lp script pug-pe
Lp script pug-peLp script pug-pe
Lp script pug-pe
 
Aula02 Pilhas
Aula02   PilhasAula02   Pilhas
Aula02 Pilhas
 
Funções em C
Funções em CFunções em C
Funções em C
 
Aula03 Filas
Aula03   FilasAula03   Filas
Aula03 Filas
 
2 funcoes e estrutura de blocos
2   funcoes e estrutura de blocos2   funcoes e estrutura de blocos
2 funcoes e estrutura de blocos
 
Aula apontadores
Aula apontadoresAula apontadores
Aula apontadores
 

Andere mochten auch (8)

Apostila estrutura de dados 2
Apostila estrutura de dados 2Apostila estrutura de dados 2
Apostila estrutura de dados 2
 
Pilha de batata
Pilha de batata Pilha de batata
Pilha de batata
 
Compiladores 6
Compiladores 6Compiladores 6
Compiladores 6
 
Pilhas e Filas
Pilhas e FilasPilhas e Filas
Pilhas e Filas
 
Pilha e Fila Dinamica
Pilha e Fila DinamicaPilha e Fila Dinamica
Pilha e Fila Dinamica
 
Estrutura de dados - Pilhas
Estrutura de dados - PilhasEstrutura de dados - Pilhas
Estrutura de dados - Pilhas
 
Pilhas
PilhasPilhas
Pilhas
 
Pilhas
PilhasPilhas
Pilhas
 

Ähnlich wie 6 alocacao sequencial - pilhas

7 alocacao sequencial - filas
7   alocacao sequencial - filas7   alocacao sequencial - filas
7 alocacao sequencial - filasRicardo Bolanho
 
Programação Orientada a Objetos - Conceitos básicos da linguagem JAVA
Programação Orientada a Objetos - Conceitos básicos da linguagem JAVAProgramação Orientada a Objetos - Conceitos básicos da linguagem JAVA
Programação Orientada a Objetos - Conceitos básicos da linguagem JAVACristiano Almeida
 
Ruby e Erlang de mãos dadas
Ruby e Erlang de mãos dadasRuby e Erlang de mãos dadas
Ruby e Erlang de mãos dadasÉverton Ribeiro
 
Aula - Funções (Curso de Python Básico -- FATEC SENAI MT)
Aula - Funções (Curso de Python Básico -- FATEC SENAI MT)Aula - Funções (Curso de Python Básico -- FATEC SENAI MT)
Aula - Funções (Curso de Python Básico -- FATEC SENAI MT)Filipe Chagas Ferraz
 
mod3-programação-estruturada
mod3-programação-estruturadamod3-programação-estruturada
mod3-programação-estruturadadiogoa21
 
2016/01/27 - Aprendendo a programar com Python
2016/01/27 - Aprendendo a programar com Python2016/01/27 - Aprendendo a programar com Python
2016/01/27 - Aprendendo a programar com PythonJardel Weyrich
 
Programação Estruturada 2 - Aula 06
Programação Estruturada 2 - Aula 06Programação Estruturada 2 - Aula 06
Programação Estruturada 2 - Aula 06thomasdacosta
 
095 A 134 Material Auxiliar Para Curso AvançAdo I Msp430
095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430
095 A 134 Material Auxiliar Para Curso AvançAdo I Msp430Texas Instruments
 
Usando POP com Programação Funcional
Usando POP com Programação FuncionalUsando POP com Programação Funcional
Usando POP com Programação FuncionalTales Andrade
 

Ähnlich wie 6 alocacao sequencial - pilhas (20)

Pilhas
PilhasPilhas
Pilhas
 
Aula 7 -_aed_-_sub_algoritmos
Aula 7 -_aed_-_sub_algoritmosAula 7 -_aed_-_sub_algoritmos
Aula 7 -_aed_-_sub_algoritmos
 
Aula 7 aed - sub algoritmos
Aula 7   aed - sub algoritmosAula 7   aed - sub algoritmos
Aula 7 aed - sub algoritmos
 
7 alocacao sequencial - filas
7   alocacao sequencial - filas7   alocacao sequencial - filas
7 alocacao sequencial - filas
 
Simulink 4
Simulink 4Simulink 4
Simulink 4
 
Programação Orientada a Objetos - Conceitos básicos da linguagem JAVA
Programação Orientada a Objetos - Conceitos básicos da linguagem JAVAProgramação Orientada a Objetos - Conceitos básicos da linguagem JAVA
Programação Orientada a Objetos - Conceitos básicos da linguagem JAVA
 
Pged 05
Pged 05Pged 05
Pged 05
 
Ruby e Erlang de mãos dadas
Ruby e Erlang de mãos dadasRuby e Erlang de mãos dadas
Ruby e Erlang de mãos dadas
 
Aula - Funções (Curso de Python Básico -- FATEC SENAI MT)
Aula - Funções (Curso de Python Básico -- FATEC SENAI MT)Aula - Funções (Curso de Python Básico -- FATEC SENAI MT)
Aula - Funções (Curso de Python Básico -- FATEC SENAI MT)
 
mod3-programação-estruturada
mod3-programação-estruturadamod3-programação-estruturada
mod3-programação-estruturada
 
2016/01/27 - Aprendendo a programar com Python
2016/01/27 - Aprendendo a programar com Python2016/01/27 - Aprendendo a programar com Python
2016/01/27 - Aprendendo a programar com Python
 
Simulador Funcional
Simulador FuncionalSimulador Funcional
Simulador Funcional
 
Programação Estruturada 2 - Aula 06
Programação Estruturada 2 - Aula 06Programação Estruturada 2 - Aula 06
Programação Estruturada 2 - Aula 06
 
Comandos e expressões
Comandos e expressõesComandos e expressões
Comandos e expressões
 
Comandos de controle de fluxo do php
Comandos de controle de fluxo do phpComandos de controle de fluxo do php
Comandos de controle de fluxo do php
 
Introdução ao paradigma funcional com scala
Introdução ao paradigma funcional com scalaIntrodução ao paradigma funcional com scala
Introdução ao paradigma funcional com scala
 
Apostila rpira
Apostila rpiraApostila rpira
Apostila rpira
 
Aula de C e C++
Aula de C e C++Aula de C e C++
Aula de C e C++
 
095 A 134 Material Auxiliar Para Curso AvançAdo I Msp430
095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430095 A 134   Material Auxiliar Para Curso AvançAdo I Msp430
095 A 134 Material Auxiliar Para Curso AvançAdo I Msp430
 
Usando POP com Programação Funcional
Usando POP com Programação FuncionalUsando POP com Programação Funcional
Usando POP com Programação Funcional
 

Mehr von Ricardo Bolanho

19 algoritmos de enumeracao
19   algoritmos de enumeracao19   algoritmos de enumeracao
19 algoritmos de enumeracaoRicardo Bolanho
 
18 algoritmos de busca de palavras em texto
18   algoritmos de busca de palavras em texto18   algoritmos de busca de palavras em texto
18 algoritmos de busca de palavras em textoRicardo Bolanho
 
17 arvores binarias de busca
17   arvores binarias de busca17   arvores binarias de busca
17 arvores binarias de buscaRicardo Bolanho
 
16 algoritmos de busca em tabelas - hash
16   algoritmos de busca em tabelas - hash16   algoritmos de busca em tabelas - hash
16 algoritmos de busca em tabelas - hashRicardo Bolanho
 
15 algoritmos de busca em tabelas - sequencial e binaria
15   algoritmos de busca em tabelas - sequencial e binaria15   algoritmos de busca em tabelas - sequencial e binaria
15 algoritmos de busca em tabelas - sequencial e binariaRicardo Bolanho
 
14 algoritmos de classificacao de tabelas
14   algoritmos de classificacao de tabelas14   algoritmos de classificacao de tabelas
14 algoritmos de classificacao de tabelasRicardo Bolanho
 
13 introducao a analise de algoritmos
13   introducao a analise de algoritmos13   introducao a analise de algoritmos
13 introducao a analise de algoritmosRicardo Bolanho
 
12 algoritmos e funcoes recursivas
12   algoritmos e funcoes recursivas12   algoritmos e funcoes recursivas
12 algoritmos e funcoes recursivasRicardo Bolanho
 
11 tipos abstratos de dados
11   tipos abstratos de dados11   tipos abstratos de dados
11 tipos abstratos de dadosRicardo Bolanho
 
10 alocacao dinamica - listas ligadas
10   alocacao dinamica - listas ligadas10   alocacao dinamica - listas ligadas
10 alocacao dinamica - listas ligadasRicardo Bolanho
 
8 ponteiros, ponteiros e vetores e alocacao dinamica de memoria
8   ponteiros,  ponteiros e vetores e alocacao dinamica de memoria8   ponteiros,  ponteiros e vetores e alocacao dinamica de memoria
8 ponteiros, ponteiros e vetores e alocacao dinamica de memoriaRicardo Bolanho
 
5 expressoes logicas - operadores - base binaria - operadores de bits
5   expressoes logicas - operadores - base binaria - operadores de bits5   expressoes logicas - operadores - base binaria - operadores de bits
5 expressoes logicas - operadores - base binaria - operadores de bitsRicardo Bolanho
 
3 funcoes vetores matrizes
3   funcoes vetores matrizes3   funcoes vetores matrizes
3 funcoes vetores matrizesRicardo Bolanho
 
Lógica para computação silva-finger-melo
Lógica para computação   silva-finger-meloLógica para computação   silva-finger-melo
Lógica para computação silva-finger-meloRicardo Bolanho
 
00 essential raymond murphy
00 essential raymond murphy00 essential raymond murphy
00 essential raymond murphyRicardo Bolanho
 
Symon,kr.mecanica.3 e,1996pt,341p
Symon,kr.mecanica.3 e,1996pt,341pSymon,kr.mecanica.3 e,1996pt,341p
Symon,kr.mecanica.3 e,1996pt,341pRicardo Bolanho
 

Mehr von Ricardo Bolanho (20)

19 algoritmos de enumeracao
19   algoritmos de enumeracao19   algoritmos de enumeracao
19 algoritmos de enumeracao
 
18 algoritmos de busca de palavras em texto
18   algoritmos de busca de palavras em texto18   algoritmos de busca de palavras em texto
18 algoritmos de busca de palavras em texto
 
17 arvores binarias de busca
17   arvores binarias de busca17   arvores binarias de busca
17 arvores binarias de busca
 
16 algoritmos de busca em tabelas - hash
16   algoritmos de busca em tabelas - hash16   algoritmos de busca em tabelas - hash
16 algoritmos de busca em tabelas - hash
 
15 algoritmos de busca em tabelas - sequencial e binaria
15   algoritmos de busca em tabelas - sequencial e binaria15   algoritmos de busca em tabelas - sequencial e binaria
15 algoritmos de busca em tabelas - sequencial e binaria
 
14 algoritmos de classificacao de tabelas
14   algoritmos de classificacao de tabelas14   algoritmos de classificacao de tabelas
14 algoritmos de classificacao de tabelas
 
13 introducao a analise de algoritmos
13   introducao a analise de algoritmos13   introducao a analise de algoritmos
13 introducao a analise de algoritmos
 
12 algoritmos e funcoes recursivas
12   algoritmos e funcoes recursivas12   algoritmos e funcoes recursivas
12 algoritmos e funcoes recursivas
 
11 tipos abstratos de dados
11   tipos abstratos de dados11   tipos abstratos de dados
11 tipos abstratos de dados
 
10 alocacao dinamica - listas ligadas
10   alocacao dinamica - listas ligadas10   alocacao dinamica - listas ligadas
10 alocacao dinamica - listas ligadas
 
9 structs e ponteiros
9   structs e ponteiros9   structs e ponteiros
9 structs e ponteiros
 
8 ponteiros, ponteiros e vetores e alocacao dinamica de memoria
8   ponteiros,  ponteiros e vetores e alocacao dinamica de memoria8   ponteiros,  ponteiros e vetores e alocacao dinamica de memoria
8 ponteiros, ponteiros e vetores e alocacao dinamica de memoria
 
5 expressoes logicas - operadores - base binaria - operadores de bits
5   expressoes logicas - operadores - base binaria - operadores de bits5   expressoes logicas - operadores - base binaria - operadores de bits
5 expressoes logicas - operadores - base binaria - operadores de bits
 
4 char e strings
4   char e strings4   char e strings
4 char e strings
 
3 funcoes vetores matrizes
3   funcoes vetores matrizes3   funcoes vetores matrizes
3 funcoes vetores matrizes
 
Lógica para computação silva-finger-melo
Lógica para computação   silva-finger-meloLógica para computação   silva-finger-melo
Lógica para computação silva-finger-melo
 
Projeto 2 aula 5
Projeto 2   aula 5Projeto 2   aula 5
Projeto 2 aula 5
 
Projeto 1 aula 4
Projeto 1   aula 4Projeto 1   aula 4
Projeto 1 aula 4
 
00 essential raymond murphy
00 essential raymond murphy00 essential raymond murphy
00 essential raymond murphy
 
Symon,kr.mecanica.3 e,1996pt,341p
Symon,kr.mecanica.3 e,1996pt,341pSymon,kr.mecanica.3 e,1996pt,341p
Symon,kr.mecanica.3 e,1996pt,341p
 

6 alocacao sequencial - pilhas

  • 1. Alocação seqüencial - pilhas Mac122 – Marcilio Alocação sequencial - Pilhas Pilhas A estrutura de dados Pilha é bastante intuitiva. A analogia é uma pilha de pratos. Se quisermos usar uma pilha de pratos com a máxima segurança, devemos inserir um novo prato “no topo” da pilha e retirar um novo prato “do topo” da pilha. Por isso dizemos que uma pilha é caracterizada pelas seguintes operações: O último a entrar é o primeiro a sair ou O primeiro a entrar é o último a sair Os nomes usados em inglês são: LIFO – last in first out ou FILO – first in last out Considere o exemplo abaixo que mostra a evolução de uma pilha.  Uma letra significa empilhe a letra;  Um ponto significa desempilhe uma letra; operação E X E . . M P . . . L O . D E P I . . . . . . L retirado E X L P M E O I P E D L Alocação seqüencial - pilhas Mac122 – Marcilio Pilha E EX EXE EX E EM EMP EM E L LO L LD LDE LDEP LDEPI LDEP LDE LD L Erro – pilha vazia L
  • 2. Alocação seqüencial - pilhas Mac122 – Marcilio H A LH LHA A implementação de uma pilha num vetor de inteiros ficaria: int pilha[MAX]; /* pilha[0] ... pilha[MAX-1] */ int topo; /* indica elemento de cima da pilha */ /* inicia pilha */ void inicia_pilha () { topo = -1; } /* empilha novo elemento */ int empilha(int x) { if (topo == MAX-1) return -1; /* não há mais espaço */ topo++; pilha[topo] = x; return 0; } /* desempilha novo elemento */ int desempilha(int *x) { if (topo < 0) return -1; /* pilha vazia */ *x = pilha[topo]; topo--; return 0; } Usamos acima uma pilha de inteiros (int), mas poderíamos usar as mesmas funções com uma pilha de elementos de qualquer um dos tipos básicos (char, float, double, etc.). Não haveria mudança mesmo se a pilha fosse de elementos do tipo struct. Veja abaixo: /* cada um dos elementos da pilha */ struct elemento { ... } struct elemento pilha[MAX]; int topo; /* inicia pilha */ void inicia_pilha () { topo = -1; } /* empilha novo elemento */ Alocação seqüencial - pilhas Mac122 – Marcilio
  • 3. Alocação seqüencial - pilhas Mac122 – Marcilio int empilha(struct elemento x) { if (topo == MAX-1) return -1; /* não há mais espaço */ topo++; pilha[topo] = x; return 0; } /* desempilha novo elemento */ int desempilha(struct elemento *x) { if (topo < 0) return -1; /* pilha vazia */ *x = pilha[topo]; topo--; return 0; } Aplicações A estrutura de pilha é uma estrutura fundamental em muitas aplicações da computação. Citamos alguns: a) Na execução de um programa, quando se entra num novo bloco, podem existir novas variáveis. Estas novas variáveis são alocadas numa pilha de variáveis, pois na saída do bloco o espaço ocupado deve ser liberado para dar lugar a novas variáveis quando a execução entrar em novos blocos. A b {int a,b; ....... a b x y x {int x,y,z; ....... a b x y X { int b, k; ..... a b x y x } ........ } a b ........ } b k b) A tabela de símbolos de um compilador, onde ficam as variáveis declaradas tem uma estrutura de pilha. Note que variáveis podem ter o mesmo nome em blocos diferentes e usase sempre a que foi declarada por último. Assim a busca na tabela de símbolos deve ser feita sempre do fim para o começo. Além disso, quando termina um bloco onde há variáveis locais, estas desaparecem da tabela de símbolos. c) O próprio algoritmo de análise sintática (aquele algoritmo que verifica se a sintaxe do programa está correta) usa uma pilha sintática, para guardar o contexto do programa sendo Alocação seqüencial - pilhas Mac122 – Marcilio
  • 4. Alocação seqüencial - pilhas Mac122 – Marcilio analisado (para entender melhor isso seria necessário conhecer melhor esses algoritmos, o que não é objeto deste curso). d) Suponha que durante a execução de um programa, uma função f, chama uma função g, que chama uma função h. Obviamente, depois da execução de h, deve-se voltar para g e depois de g, voltar para f. Os endereços de retorno após a chamada de uma função, são colocados numa pilha de execução, para que se volte para o lugar certo. e) Um caso especial é quando usamos funções recursivas. Como a função chamada é sempre a mesma, o controle dos endereços de retorno e dos parâmetros de cada chamada, é feito pela pilha de execução. Os parâmetros de cada chamada são também empilhados. Notação pós-fixa para expressões A notação pós-fixa para expressões, também chamada de notação polonesa, pois foi inventada pelo matemático polonês Jan Łukasiewicz (1878 - 1956) e usada pela primeira vez em computação pelo cientista de computação Charles Hamblin em 1957, apresenta uma série de facilidades em relação a notação tradicional. Nela os operadores aparecem após os operandos e não entre os operandos. Exemplos: 1 2 3 4 5 6 7 Notação usual (in-fixa) a+b a+b+c a+b*c (a+b)*c c*(a+b) b^2-4*a*c (-b+√( b^2-4*a*c))/(2*a) Notação polonesa (pós-fixa) ab+ ab+c+ ou abc++ abc*+ ab+c* cab+* B2^4a*c*- ou b2^4ac**b-b2^4ac**-√+2ª*/ Algumas observações sobre a notação pós-fixa: a) Essa notação elimina a necessidade de parêntesis. b) Pode existir mais de uma solução (exemplos 2 e 6) devido a mesma prioridade dos operandos envolvidos. Nos 2 exemplos acima, é melhor considerar a primeira solução, pois a convenção usual é que quando temos operadores de mesma prioridade (no exemplo 2 ++ e no exemplo 6 **) as operações são feitas da esquerda para a direita. c) Os operandos aparecem na mesma ordem em que se encontram na expressão original. d) Podemos usar também os operadores unários. No caso do exemplo 7, usamos os operadores – (unário) e √ (raiz quadrada). No caso dos operadores unários – e + que possuem o mesmo símbolo dos binários correspondentes tem que se fazer a distinção usando outro símbolo para que não haja dúvida sobre a operação. e) Para se calcular o valor da expressão em notação pós-fixa, varre-se a expressão da esquerda para a direita simplesmente. Não é necessário verificar qual a operação que se faz primeiro por que tem mais prioridade ou porque está entre parêntesis. Alocação seqüencial - pilhas Mac122 – Marcilio
  • 5. Alocação seqüencial - pilhas Mac122 – Marcilio Algoritmo para transformar uma expressão para a notação pós-fixa Varrendo a expressão norma da esquerda para a direita, o algoritmo deve levar em conta a prioridade dos operadores antes de colocá-los na expressão pós-fixa. Assim, antes de colocar um operador na expressão pós-fixa, é necessário saber se o próximo operador é menos prioritário que ele. Isso sugere usar uma pilha para os operadores. Quando chega um operador mais prioritário que o do topo da pilha, empilha-se este também. Mas se for menos prioritário, o do topo tem que ir para a expressão pós-fixa e dar lugar para este que acabou de chegar. Os parêntesis são um caso especial. Quando aparece um fecha, deve-se colocar na pós-fixa todos os operadores até o abre correspondente. while (expressão não chegou ao fim) { pegue próximo elemento p; if (p é operando) coloque na pós-fixa; if (p é operador) { tire da pilha e coloque na pós-fixa todos os operadores com prioridade maior ou igual a p, na mesma ordem de retirada da pilha; empilhe p; } if (p é abre parêntesis) empilha p; if (p é fecha parêntesis) desempilhe os operadores até o primeiro abre e coloque na pós-fixa na mesma ordem de retirada da pilha; } desempilhe todos os operadores que ainda estão na pilha e coloque na pós-fixa na mesma ordem de retirada da pilha; Os operadores devem então estar organizados por sua prioridade. A função abaixo define a prioridade dos operadores binários +, -, * , /, e ^ . Para facilitar o algoritmo damos também prioridade ao abre, fecha e a operando, embora tenham tratamento especial no algoritmo. int prioridade (char x) { switch (x) { case ‘+’: return 1; case ‘-’: return 1; case ‘*’: return 2; case ‘/’: return 2; case ‘^’: return 3; case ‘(’: return 4; case ‘)’: return 5; default : return 0; } Alocação seqüencial - pilhas Mac122 – Marcilio /* caso particular */ /* caso particular */ /* é operando */
  • 6. Alocação seqüencial - pilhas Mac122 – Marcilio } Comportamento da pilha em alguns exemplos Abaixo, exemplos do comportamento da pilha para algumas expressões: a+b Pilha a + b + + Pós-fixa a a ab ab+ a+b+c Pilha a + b + c + + + + Pós-fixa a a ab ab+ ab+c ab+c+ a*b+c Pilha a * b + c * * + + Pós-fixa a a ab ab* ab*c ab*c+ a+b*c Pilha a + b * c + + +* +* a*(b+c) Pilha a * * ( *( Alocação seqüencial - pilhas Mac122 – Marcilio Pós-fixa a a ab ab abc abc*+ Pós-fixa a a a
  • 7. Alocação seqüencial - pilhas Mac122 – Marcilio b + c ) *( *(+ *(+ * (a+b)*c Pilha ( ( a + (+ b (+ ) * * c * a*(b+(c*(d+e))) Pilha a * * ( *( b *( + *(+ ( *(+( c *(+( * *(+(* ( *(+(*( d *(+(*( + *(+(*(+ e *(+(*(+ ) *(+(* ) *(+ ) * a/(b*c)*d Pilha a / / ( /( b /( * /(* c /(* ) / * * Alocação seqüencial - pilhas Mac122 – Marcilio ab ab abc abc+ abc+* Pós-fixa a a ab ab+ ab+ ab+c ab+c* Pós-fixa a a a ab ab ab abc abc abc abcd abcd abcde abcde+ abcde+* abcde+*+ abcde+*+* Pós-fixa a a a ab ab abc abc* abc*/
  • 8. Alocação seqüencial - pilhas Mac122 – Marcilio d * abc*/d abc*/d* A prioridade dos operadores em C Nos exemplos acima, usamos os operadores mais usuais, mas todos os operadores em C tem a sua prioridade associada. Os operadores unários (+ e c-), a atribuição (=), os operadores lógicos (&& e ||), etc. seguem a mesma regra de cálculo com a sua respectiva prioridade. A tabela abaixo mostra os operadores em C com a respectiva prioridade e o mesmo algoritmo acima pode ser usado para traduzir qualquer expressão ou comando em C. Prioridade Operador () [] . -> ++ -2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Descrição Direção Pós Esquerda-Direita ++ -- ~ ! sizeof new delete Unários e pré * & Ponteiros Direita-Esquerda + Unários (type) type casting Direita-Esquerda .* ->* Ponteiros Esquerda-Direita * / % Multiplicativos Esquerda-Direita + Aditivos Esquerda-Direita << >> Shift Esquerda-Direita < > <= >= Relacional Esquerda-Direita == != Igualdade Esquerda-Direita & Bitwise AND Esquerda-Direita ^ Bitwise XOR Esquerda-Direita | Bitwise OR Esquerda-Direita && Lógico AND Esquerda-Direita || Lógico OR Esquerda-Direita ?: Condicioanl Esquerda-Direita = *= /= %= += -= >>= <<= &= ^= |= Atribuição Direita-Esquerda , Vírgula Esquerda-Direita Operadores unários e operadores binários Na notação usual os operadores + e – (adição e subtração) possuem o mesmo símbolo quando unários ou binários, embora tenham significado diferente. Essa diferença é resolvida pelos compiladores quando analisam o contexto da expressão. O ideal seria usar símbolos diferentes para operadores unários e binários. Alocação seqüencial - pilhas Mac122 – Marcilio
  • 9. Alocação seqüencial - pilhas Mac122 – Marcilio Algoritmo para o cálculo do valor de uma expressão em notação pós-fixa Uma vantagem da expressão pós-fixa é que para se calcular o seu valor o algoritmo é mais simples. Basta varrê-la da esquerda para a direita e efetuar as operações com os dois últimos operandos, ou o último no caso de operadores unários. Para tanto, os operados tem que ser empilhados à medida que aparecem, pois a operação será aplicada aos dois últimos (se for operação binária) ou apenas ao último se for uma operação unária. while (expressão pós-fixa não chegou ao fim) { pega próximo elemento p; if (p é operando) empilha p; if (p é operador unário) { faz a operação com o elemento do topo da pilha; if (p é operador binário) { faz a operação com os 2 elementos do topo da pilha; neste caso a pilha diminui de 1 elemento; } O resultado da expressão estará no topo da pilha, que ao final se reduz a um único elemento. Observe que no algoritmo de tradução, a pilha era de operadores enquanto que no algoritmo de cálculo a pilha é de operandos. Exemplo - Considere a expressão aritmética abaixo: e suponha a=1,b=2,c=3,d=4,e=5: a*(b+c*(d+e)) que na notação pós-fixa ficaria: abcde+*+* Suponha que a=1,b=2,c=3,d=4,e=5. Vamos calcular o valor da expressão já em notação pós-fixa: a 1 b 2 1 Alocação seqüencial - pilhas Mac122 – Marcilio c 3 2 1 d e + * + * 4 3 2 1 5 4 3 2 1 9 3 2 1 27 2 1 29 1 29