Pilha_Dinamica

6
Centro Federal de Educação Tecnológica do Espírito Santo Unidade de Ensino Descentralizada de Colatina Tecnólogo em Redes de Computadores 1 PROGRAMAÇÃO II Prof. Jean Eduardo Glazar 3. PILHA DINÂMICA Uma pilha é um tipo especial de Pilha na quais todas as inserções e remoções são feitas na primeira posição, que é chamada de topo. Outro nome para pilha é LIFO (Last In First Out). Um modelo intuitivo de uma pilha é, por exemplo, uma pilha de pratos dentro de uma caixa bem estreita, de modo que se quisermos pegar um prato do meio deveremos desempilhar os pratos de cima um a um ou se quisermos acrescentar pratos deveremos empilhá-los um a um. Veja o desenho abaixo. PRINCIPAIS FUNÇÕES CriarPilha – Inicia a pilha vazia. CriarNodoPilha – Aloca memória para um novo nodo e retorna o seu apontador. ObterTopo – Obtém o elemento do topo da pilha sem desempilhar. Desempilhar – Obtém o elemento do topo da pilha desempilhando. Empilhar – Insere um elemento no topo da pilha. PilhaVazia – Retorna verdadeiro se pilha vazia e falso caso contrário. Imprimir – Imprime a pilha. Destruir – Destroi a pilha, liberando a memória dos nodos. Passaremos agora para a implementação do TAD Pilha através de alocação dinâmica. Pilha para nós agora, será um ponteiro que aponta sempre para o nodo que se encontra no topo da pilha. Cada nodo terá um elemento próximo que aponta para o nodo abaixo na pilha.

Transcript of Pilha_Dinamica

Page 1: Pilha_Dinamica

Centro Federal de Educação Tecnológica do Espírito Santo

Unidade de Ensino Descentralizada de Colatina

Tecnólogo em Redes de Computadores

1

PROGRAMAÇÃO II Prof. Jean Eduardo Glazar

3. PILHA DINÂMICA Uma pilha é um tipo especial de Pilha na quais todas as inserções e remoções são feitas na primeira posição, que é chamada de topo. Outro nome para pilha é LIFO (Last In First Out).

Um modelo intuitivo de uma pilha é, por exemplo, uma pilha de pratos dentro de uma caixa bem estreita, de modo que se quisermos pegar um prato do meio deveremos desempilhar os pratos de cima um a um ou se quisermos acrescentar pratos deveremos empilhá-los um a um. Veja o desenho abaixo.

PRINCIPAIS FUNÇÕES

CriarPilha – Inicia a pilha vazia.

CriarNodoPilha – Aloca memória para um novo nodo e retorna o seu apontador.

ObterTopo – Obtém o elemento do topo da pilha sem desempilhar.

Desempilhar – Obtém o elemento do topo da pilha desempilhando.

Empilhar – Insere um elemento no topo da pilha.

PilhaVazia – Retorna verdadeiro se pilha vazia e falso caso contrário.

Imprimir – Imprime a pilha.

Destruir – Destroi a pilha, liberando a memória dos nodos.

Passaremos agora para a implementação do TAD Pilha através de alocação dinâmica. Pilha para nós agora, será um ponteiro que aponta sempre para o nodo que se encontra no topo da pilha. Cada nodo terá um elemento próximo que aponta para o nodo abaixo na pilha.

Page 2: Pilha_Dinamica

Centro Federal de Educação Tecnológica do Espírito Santo

Unidade de Ensino Descentralizada de Colatina

Tecnólogo em Redes de Computadores

2

A pilha vazia será representada pelo topo apontando para NULL.

Ao empilhar um novo nodo, o topo passará a apontar para este nodo e o próximo do novo nodo será o antigo topo.

Inserindo o elemento 5:

Inserindo o elemento 3:

Ao desempilhar, o topo passará a apontar para o próximo elemento da pilha (topo:=topo^.prox).

Desempilhando:

O elemento 3 deverá ser desalocado.

Veja a mudança da estrutura de dados e das funções abaixo.

Definição

TYPE Informacao = RECORD

{ Conteudo de cada posição da pilha, por exemplo: nome, cpf, telefone, etc ... }

END;

TYPE Ponteiro = ^NodoPilha;

Page 3: Pilha_Dinamica

Centro Federal de Educação Tecnológica do Espírito Santo

Unidade de Ensino Descentralizada de Colatina

Tecnólogo em Redes de Computadores

3

TYPE NodoPilha = RECORD

info : Informacao;

prox : Ponteiro; { Próximo elemento }

END;

TYPE Pilha = RECORD

topo : Ponteiro; { Topo da pilha}

tamanho : INTEGER; { Tamanho da Pilha }

END;

ALGUMAS IMPLEMENTAÇÕES:

{###### Inicializar a pilha vazia ######}

procedure CriarPilha ( var P : Pilha); begin P.topo := NIL; { Pilha vazia. Apontador aponta para nada} P.tamanho := 0; end; {###### Retorna TRUE se a Pilha estiver vazia ##### ####### e FALSE caso contrario ##### }

FUNCTION PilhaVazia ( VAR P : Pilha ) : BOOLEAN; BEGIN IF ( P.topo = NIL ) THEN PilhaVazia := TRUE ELSE PilhaVazia := FALSE; END; {###### Aloca memória para um determinado NODO e ######} {###### retorna o apontador para este NODO. Se não for possível } {###### alocar memória, retorna NIL ######}

FUNCTION CriarNodoPilha ( e : informacao ) : Ponteiro; VAR aux : Ponteiro; BEGIN IF MaxAvail < SIZEOF(NodoPilha) { ** Testa se existe memória *} THEN BEGIN

WRITELN(‘Não existe memória suficiente’); CriarNodoPilha := NIL; END

ELSE BEGIN NEW(aux); aux^.info := e; {** Copiar todo o registro de E para INFO} CriarNodoPilha := aux; END;

END;

Page 4: Pilha_Dinamica

Centro Federal de Educação Tecnológica do Espírito Santo

Unidade de Ensino Descentralizada de Colatina

Tecnólogo em Redes de Computadores

4

{ #### Empilhar o NOVO nodo no TOPO da pilha ####} { #### O NOVO nodo deve ter sido criado com a função CriarNodo ####}

PROCEDURE Empilhar (VAR P : Pilha; novo : Ponteiro); BEGIN IF novo = NIL THEN BEGIN WRITELN(‘Não existe nodo para inserir’); END ELSE BEGIN

novo^.prox := P.topo; P.topo := novo; P.tamanho := P.tamanho + 1;

END END; { #### Desempilha o elemento do TOPO da pilha ####} { #### e libera a memória ####}

PROCEDURE Desempilhar(VAR P : Pilha); VAR aux : Ponteiro; BEGIN IF ( PilhaVazia(P) )

THEN WRITELN('Pilha Vazia') ELSE BEGIN aux := P.topo;

P.topo := P.topo^.prox; { Remover o primeiro } DISPOSE(aux); P.tamanho := P.tamanho – 1; END; END;

Não podemos esquecer de destruir toda a Pilha, ou seja, desalocar todos os elementos antes do nosso programa terminar. Para isso, vamos criar a função Destruir, que irá percorrer toda a Pilha eliminando cada elemento.

{ #### Destroi a Pilha liberando a memória ####} { #### Percorre a Pilha desempilhando o topo ####} PROCEDURE Destruir (VAR P : Pilha); BEGIN WHILE ( NOT PilhaVazia(P) ) DO BEGIN

Desempilhar(P); {*** Desempilha o topo ***} END; END; As demais funções ficam como exercícios.

Page 5: Pilha_Dinamica

Centro Federal de Educação Tecnológica do Espírito Santo

Unidade de Ensino Descentralizada de Colatina

Tecnólogo em Redes de Computadores

5

{*** Vejamos agora o programa principal utilizando esta Pilha ***} {*** Declaração ***}

VAR P : Pilha; el : informacao; pt : Ponteiro; {*** Programa principal ***}

BEGIN CriarPilha(P); el.nome := 'A'; Empilhar(P, CriarNodoPilha(el) ); el.nome := 'B'; Empilhar(P, CriarNodoPilha(el) ); el.nome := 'C'; Empilhar(P, CriarNodoPilha(el) ); el.nome := 'D'; Empilhar(P, CriarNodoPilha(el) ); el.nome := 'E'; Empilhar(P, CriarNodoPilha(el) ); el.nome := 'F'; Empilhar(P, CriarNodoPilha(el) ); el.nome := 'G'; Empilhar(P, CriarNodoPilha(el) ); Imprimir(P); {*** Imprime: G F E D C B A ***} Desempilhar(P); Imprimir(P); {*** Imprime: F E D C B A ***} pt := ObterTopo(P); IF ( pt <> nil )

THEN writeln(pt^.info.nome); {*** Imprime: F ***} Desempilhar(P); Imprimir(P); {*** Imprime: E D C B A ***} Desempilhar(P); Imprimir(P); {*** Imprime: D C B A ***} Desempilhar(P); Imprimir(P); {*** Imprime: C B A ***} pt := ObterTopo(P); IF ( pt <> nil )

THEN writeln(pt^.info.nome); {*** Imprime: C ***} Destruir(P); {*** Não esqueça de destruir a Pilha ***} readkey; END.

Page 6: Pilha_Dinamica

Centro Federal de Educação Tecnológica do Espírito Santo

Unidade de Ensino Descentralizada de Colatina

Tecnólogo em Redes de Computadores

6

A vantagem de se utilizar pilha por vetor é a simplicidade de implementá-la. A desvantagem é que tem tamanho limitado. Então, dependerá da sua necessidade. Se for certo que a pilha a utilizar não crescerá mais que um determinado tamanho conhecido, então pode-se perfeitamente utilizar uma pilha por vetores. Se, no entanto, a pilha puder crescer indefinidamente, a melhor opção será utilizar pilha por alocação dinâmica.

EXERCÍCIOS:

1) Implemente as funções que estão faltando.

2) Considere a implementação da Pilha utilizando a alocação dinâmica:

a) Represente a Pilha vazia e após cada inserção dos elementos 8, 4, 5, 3 e 9.

b) Represente a Pilha após desempilhar um elementos.

c) Represente a Pilha após desempilhar mais um elementos.

d) Escreva uma rotina em C para imprimir a Pilha.

e) Escreva uma rotina em C para esvaziar a Pilha.

3) Faça um programa em C para converter um número decimal em binário, utilizando uma pilha de inteiros para empilhar os restos das divisões por dois, necessárias para a conversão.

4) Escreva um programa que verifique que expressões aritméticas estão com a parentização correta. Guarde o resultado numa pilha também. Seu programa deve checar expressões para ver se cada "abre parênteses" tem um "fecha parênteses" correspondente.