Estrutura de Dados com Objetos em Delphi - Pilha (Stack)

Extraído do site: www.planetadelphi.com.br

 

Olá pessoal, bem vindo ao meu primeiro artigo à comunidade.

Tratarei de estrutura de dados em Delphi com objetos utilizando Pilha. Isso mesmo. Aquela estrutura de dados onde o último elemento a ser inserido será o primeiro a sair, do inglês a sigla LIFO (last in, first out).
Não precisam se preocupar em como isso é fácil ou difícil, o único requisito é saber um pouco de orientação à objeto e como essa estrutura (pilha) funciona. Isso porque é fundamental à nós desenvolvedores conhecer o porquê das coisas; como essa e outras estruturas, tais como listas em forma de fila, árvores binárias, etc., trabalham.
Vamos lá! Assim como Java, o Delphi possui classes prontas para trabalhar essa e outras estruturas. Isso mesmo! Eu também fiquei muito feliz quando soube que não precisaria “reinventar a roda”. Está quase tudo implementado. Os métodos para inserir, remover, contar, controle de tamanho, etc.
A classe que utilizei para este pequeno exemplo é a TObjectStack da unit Contnrs que implementa uma pilha de TOBjects (objetos).
Para fazer parte deste exemplo, criei uma classe simples chamada TPessoa com atributo apenas para nome e idade e seus respectivos métodos Sets e Gets para alterar e consultar os atributos. Antes que me esqueça: a classe TPessoa está bastante incompleta pois o foco deste artigo é exemplificar o uso da classe TObjectStack.
· Primeiro crie uma nova aplicação e crie um Form básico como o da figura abaixo. Para isso utilize:
1. TLabelEdit paea o campo Nome e o renomeie para lbedNome;
2. 1 TLabel e 1 TEdit e renomeie o TEdit para edtIdade;
3. Adicione um TUpDown e coloque a propriedade Associate para edtIdade;
4. Adicione 5 TBitBtn e os renomeie sendo btnInserir, btnQtde, btnRemover, btnLista e BtnLimpa;
5. Adicione um TListBox e o renomeie para lstPilha
6. Adicione um TStatusBar e o renomeie para stbAutor


pilha.jpg

Concluído a etapa de desenho vamos a criação da classe TPessoa. Para isso faremos o seguite:
Logo abaixo da Type ..end responsável pela criação do TForm1 faremos uma outra como segue:

{Classe Pessoa}
type
TPessoa = class
private
idade: integer;
nome: string;
public
procedure setNome(nome: string);
procedure setIdade(idade: integer);
function getIdade(p: TPessoa):integer;
function getNome(p: TPessoa): string;
end;

No fim da Unit adicione o corpo dos métodos:
{Retorna a Idade}
function TPessoa.getIdade(p: TPessoa): integer;
begin
result:= p.idade;
end;

{Retorna o nome}
function TPessoa.getNome(p: TPessoa): string;
begin
result:= p.nome;
end;

{Seta a idade}
procedure TPessoa.setIdade(idade: integer);
begin
pessoa.idade := idade;
end;

{Seta o nome}

procedure TPessoa.setNome(nome: string);
begin
pessoa.nome:= nome;
end;

Pronta a classe, declare duas variáveis globais para “desencargo de consciência” logo abaixo da declaração do Form1, assim:
var
Form1: TForm1;
pilha: TObjectStack;
pessoa: TPessoa;

Feito isto agora vamos ao restante da implementação:

» No Evento OnCreate do Form digite:
pilha := TObjectStack.Create;
{Para criar o objeto pilha.}

» No Evento OnClick do botão BtnInserir digite:
if(edtIdade.Text <> '0') and (lbedNome.Text <>'') then
begin
{Cria um nova instância do objeto pessoa.}
pessoa := TPessoa.Create;
pessoa.setNome(lbedNome.Text);
pessoa.setIdade(StrToInt(edtIdade.text));
{Adiciona à pilha}
pilha.Push(pessoa);
end else
ShowMessage('Digite um Nome e uma Idade diferente de Zero!');
end;

» No evento OnClick botão btnQtde digite:
begin
if(pilha.Count > 0) then
ShowMessage(IntToStr(pilha.count) + ' Objeto(s)')
else
ShowMessage('Pilha vazia!');
end;

» No evento OnClick do botão BtnRemover digite:
{Exlui os objetos (desempilha)}
begin
if(pilha.Count > 0) then
pilha.Pop
else
ShowMessage('Pilha vazia!');
end;

» No evento OnClick do botão BtnLista digite:
{Adiciona ao TListBox e Exclui todos os objetos(desempilha)}
var
aux: TPessoa;
i: integer;
begin
for i:=1 to pilha.Count do begin
aux := TPessoa(pilha.Pop);
lstpilha.Items.Add(IntToStr(i) + '- Nome: ' + aux.getNome(aux) +
', Idade: ' + IntToStr(aux.getIdade(aux)));
end;
end;

» No evento OnClick do botão BtnLimpa digite:
{Zera tudo, desaloca a Pilha e chama o método FormCreate do form onde está implementado o trecho de código para criar a Pilha}
begin
lbedNome.Clear;
edtIdade.text := '0';
lstpilha.Clear;
lbedNome.SetFocus;
pilha.Free;
FormCreate(Self);
end;

Um pequeno resumo:
Utilizamos a classe TObjectStack da Unit Contnrs. Esta classe implementa um pilha de TObjects, que podem ser desde TButtons, TLabels à diversas classes criadas pelo desenvolvedor. Como a TPessoa que criamos aqui.
Neste exemplo todo nome e idade informada ao objeto do tipo TPessoa é inserido na pilha e não há preocupação com o seu limite de armazenamento, a TObjectStack trata disto internamente.
Os métodos mais utilizados no exemplo foram:

Push(TObject):TObject;

Insere

Pop:TObject;

Remove

Count: Integer;

Retorna a quantidade de objetos

Create;

Instancia

Free;

Libera os recursos;

 

O download dos fontes poder ser feitos AQUI.

Por enquanto é isso pessoal. Se houver interesse por parte da comunidade estaremo disponibilizndo exemplos com outros tipos de estruturas.
Um grande abraço e até a próxima!
Qualquer dúvida, sugestão ou crítica será bem vinda.
e-mail: fercesarb2@ig.com.br

Fernando César Brito
Graduando Ciência da Computação