Você está na página 1de 46

CENTRO EDUCACIONAL FUCAPI

CURSO TCNICO INFORMTICA


APOSTILA ESTRUTURA DE DADOS

APOSTILA

ESTRUTURA
DE DADOS

MANAUS 2013

ESTRUTURA DE DADOS PGINA 1

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

ABSTRAO DE DADOS
Um processo qualquer seqncia finita e ordenada de passos que visa promover
transformaes definidas sobre uma determinada matria-prima. Se denominamos entrada a
matria-prima no seu estado inicial; e sada o que se obtm aps as transformaes
realizadas pelo processo, temos o esquema geral a seguir:

ENTRADA

SADA

PROCESSAMENTO

(Estado Inicial)

(Estado Final)

Entrada/sada de um processo
Matria-prima abstrata: processamento de dados.
Abstrata: apresenta-se sob a forma de valores.
Processamento realizado pelo computador:
Entrada: dados colhidos do mundo real externo ao computador;
Processo: srie finita de operaes que so realizadas a partir desses dados;
Sada: transformao sofrida pelos dados atravs de um processo.

DADOS

CONHECIMENTO

INFORMAO

processamento de dados
Exemplo:

Raio R de uma
circunferncia

P=2..R

Permetro P da
circunferncia

ESTRUTURA DE DADOS PGINA 2

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

TIPOS ABSTRATOS DE DADOS


OBJETIVOS DAS ESTRUTURAS DE DADOS
TIPOS DE D ADOS (TD S)
Embora os termos "tipos de dados", "estruturas de dados" e "tipos abstratos de dados" sejam
parecidos, tm significados diferentes. Em linguagens de programao o tipo de dados de
uma varivel define o conjunto de valores que a varivel pode assumir. Exemplo: BOOLEAN
pode assumir valores TRUE ou FALSE. A declarao de uma varivel em Pascal especifica
duas coisas:
1. Quantidade de bytes reservados para a varivel (ex. 2bytes);
2. Como o dado representado por esses bytes pode ser interpretado. (ex. 2 bytes = 16 bits =
65536 combinaes. Um integer interpretado de -32767 a 32768 sendo o ponto "zero"
bem no meio desses dois bytes).
Tipos de Dados: So mtodos para interpretar o contedo da memria do
computador. Exemplo de conjunto bsico de tipos de dados primitivos (inteiro, real,
caractere, lgico) oferecidos pelas linguagens de programao; e agrupamentos
complexos de dados desses tipos primitivos (vetor, registro, ponteiro).
var
numero :integer;
letra :char;
cadeia :string;
vetor :array[1..10] of integer;
registro :record
quebrado :real;
logico :boolean;
end;

TIPOS ABSTRATOS DE D ADOS (TADS)


Viso de conceito de Tipo de Dados (perspectivas diferentes):

Computador - interpreta bits;


Usurio - deseja realizar uma operao (somar dois nmeros)
O conceito de Tipo de Dado divorciado do hardware chamado TAD.
TAD - formado por um conjunto de valores e uma srie de funes que podem ser aplicadas
sobre estes valores.
Funes + valores (em conjunto) = modelo matemtico empregado para "modelar" e
solucionar problemas do mundo real:
Especifica caractersticas relevantes dos objetos envolvidos no problema;
Especifica forma com que eles se relacionam; e
Especifica como podem ser manipulados.

ESTRUTURA DE DADOS PGINA 3

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

TAD no leva em considerao como os valores so representados na memria do


computador e nem se preocupa com o "tempo" gasto para aplicar as funes sobre tais
valores.
Exemplos:
Listas;
Pilhas;
Filas;

AS ESTRUTURAS DE D ADOS (ED S)


um mtodo particular de implementar um TAD. A implementao de um TAD escolhe uma
ED para represent-lo. Cada ED constituda de tipos bsicos (integer, char, real) ou dos
tipos estruturas (array, record) de uma linguagem.

TAD (Modelo
Matemtico)

IMPLEMENTAO

TCD (Padro
bits, Rotinas)

Implementao: transformao de TAD em um Tipo Concreto de Dados.


OBJETIVO DAS ESTRUTURAS DE DADOS:

Terico: Identificar e desenvolver modelos matemticos, determinando que classes


de problemas podem ser resolvidos com o uso deles.
Prtico: Criar representaes concretas dos objetos e desenvolver rotinas capazes
de atuar sobre essas representaes, de acordo com o modelo considerado.

LISTAS LINEARES
uma estrutura que armazena elementos de forma alinhada, ou seja, com elementos
dispostos um aps o outro, como em uma lista de nomes, peas, valores, pessoas, compras,
etc.

FUNDAMENTOS
Uma Lista Linear, uma coleo L: [a1, a2, ..., an], n>=0, cuja propriedade estrutural baseiase apenas na posio relativa dos elementos, que so dispostos linearmente. Se n=0,
dizemos que a lista L vazia; caso contrrio, so vlidas as seguintes propriedades:

a1 o primeiro elemento de L;
an o ltimo elemento de L;
ak, a<k<n, precedido pelo elemento ak-1 e seguido por ak+1 em L.
a1

a2

a3

...

an
ESTRUTURA DE DADOS PGINA 4

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Caracterstica fundamental de uma lista linear o sentido de ordem unidimensional dos


elementos que a compem. Assim, no temos dvida onde inicia ou termina a lista. Algumas
operaes com listas:

acessar um elemento qualquer;


inserir um elemento numa posio especfica;
remover um elemento de uma posio especfica;
combinar duas listas em uma nica;
particionar uma lista em duas;
obter cpias de uma lista;
determinar o total de elementos na lista;
ordenar os elementos da lista;
procurar um determinado elemento na lista;
apagar uma lista;
outras...

Uma lista com um array, pode ser implementada como uma seqncia de records com
elementos disponveis:
de forma consecutiva - Lista Esttica Seqencial;
de forma no consecutiva - Lista Esttica Encadeada;
Uma lista pode ser ordenada ou no. Pascal permite construir EDs avanadas - Lista
Dinmicas; mais versteis, utilizando ponteiros e variveis dinmicas.
Considerando apenas operaes de acesso, insero e remoo restritas aos extremos das
listas, temos casos especiais:
Pilha: insero, remoo, acesso realizados em um nico extremo. Lista LIFO.
Fila: insero num extremo e remoo, acesso no outro extremo. Lista FIFO.

ALOCAO DE MEMRIA
Para implementar uma lista linear: como podemos armazenar os elementos da lista dentro do
computador? Alocar rea de memria responsabilidade do programador e estar em uma
das quatro categorias abaixo:

ESTTICA
DINMICA

SEQENCIAL
Esttica Seqencial
Dinmica Seqencial

ENCADEADA
Esttica Encadeada
Dinmica Encadeada

ESTRUTURA DE DADOS PGINA 5

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

ALOCAO ESTTICA

X ALOCAO DINMICA

ALOCAO ESTTICA:
Quantidade total de memria utilizada pelos dados previamente conhecida e definida de
modo imutvel, no prprio cdigo-fonte do programa. Durante o programa no varia a
quantidade de memria.
ALOCAO DINMICA:
Programa cria novas variveis enquanto executa, ou seja, reas de memrias no declaradas
no programa passam a existir durante a execuo.
ESTTICA

DINMICA

Memria usada pelo programa

1FFAh
P:

1FFAh

12345
Memria livre no sistema

Um ponteiro uma varivel que contm o endereo da memria de outra varivel ou


estrutura de dados.
Uma varivel dinmica a nica estrutura de dados do Turbo Pascal que tem de estar
identificada numa declarao VAR antes de ser utilizada em um programa. O Turbo Pascal
armazena as variveis dinnmicas numa rea especial de memria chamada HEAP.
program alocacao;
type
ptr = ^integer;
var
p :ptr; {aloca varivel estaticamente}
begin
new(p); {aloca varivel dinamicamente}
p^ := 12345;
writeln(p^);
end.

Na figura anterior, P a varivel esttica e 1FFAH o endereo da varivel dinmica ou


varivel annima.
Utilizamos os comandos new() e dispose() para alocar e deslocar espaos dinmicos
respectivamente.

ESTRUTURA DE DADOS PGINA 6

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

ALOCAO SEQENCIAL X ALOCAO ENCADEADA


ALOCAO SEQENCIAL:
Consiste em colocar os elementos de uma lista em clulas de memria consecutivas, um aps
o outro.
Memria

elemento

Clula

Vantagem: Acesso rpido a um dado elemento com um simples e rpido clculo.


Ponto fraco: Ao precisar inserir ou suprimir elementos no meio da lista, ser necessrio um
certo esforo para movimentar os elementos de modo a abrir espao para insero ou ocupar
espao liberado para um elemento removido.
ALOCAO ENCADEADA:
Ao invs de manter elementos ocupando clulas consecutivas, nesta alocao os elementos
podem ocupar quaisquer clulas (no necessariamente consecutivas) e, para manter essa
relao de ordem linear, juntamente com cada elemento armazenado o endereo do
prximo elemento da lista.
Elementos armazenados em blocos de memria denominados nodos ou ns.
Cada nodo composto pelo menos por dois campos:

Dados;
Endereos.
Destaque:
Endereo do primeiro elemento da lista L;
Endereo do elemento fictcio que segue o ltimo elemento da lista (NULO, TERRA,

3FAAh

A1

1C34h

1C34h

A2

1725h

1725h

A3

ESTRUTURA DE DADOS PGINA 7

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

LISTA ESTTICA SEQENCIAL LES


Uma lista esttica seqencial um arranjo de registros onde esto estabelecidos regras de
precedncia entre seus elementos ou uma coleo ordenada de componentes do mesmo
tipo. O sucessor de um elemento ocupa posio fsica subsequente.
Ex: lista telefnica, lista de alunos .
A implementao de operaes pode ser feita utilizando array e record, onde o vetor associa o
elemento a(i) com o ndice i (mapeamento seqencial).
Caractersticas de Lista Esttica Seqencial

elementos na lista esto ordenados;


armazenados fisicamente em posies consecutivas;
insero de um elemento na posio a(i) causa o deslocamento a direita do
elemento de a(i) ao ltimo;
eliminao do elemento a(i) requer o deslocamento esquerda do a(i+1) ao ltimo;
Mas, absolutamente, uma lista esttica seqencial ou vazia ou pode ser escrita como ( a(1),
a(2), a(3), ... a(n) ) onde a(i) so tomos de um mesmo conjunto S.
Alm disso, a(1) o primeiro elemento, a(i) precede a(i+1), e a(n) o ltimo elemento.

a1
1

a2
2

an
n

Assim as propriedades estruturadas da lista permitem responder a questes como:

qual o primeiro elemento da lista;


qual o ltimo elemento da lista;
quais elementos sucedem um determinado elemento;
quantos elementos existem na lista;
inserir um elemento na lista;
eliminar um elemento da lista.

Conseqncia: As quatros primeiras operaes so feitas em tempo constante. Mas, as


operaes de insero e remoo requerero mais cuidados.
Vantagem:
acesso direto indexado a qualquer elemento da lista
tempo constante para acessar o elemento i - depender somente do ndice.

ESTRUTURA DE DADOS PGINA 8

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Desvantagem:
movimentao quando eliminado/inserido elemento
tamanho mximo pr-estimado
Quando usar:
listas pequenas
insero/remoo no fim da lista
tamanho mximo bem definido

ALGORITMOS DE INSERO E REMOO EM LES


ESTRUTURA DE DADOS E OPERAES BSICAS
DEFINIO DA ED
Const MAX=100;
Type
Lista = record
A:array[1..MAX] of integer;
n:0..MAX;
End;
Var
L: lista;
Operaes simples utilizando Lista Esttica Seqencial a serem definidas nas Units
1) Acesso a um elemento
Writeln (L.A[i]);
2) Atualizao
L.A[i]:= 'Valor'
3) Tamanho da Lista
Begin
tamanho:=L.n;
End;
4) Insero de um elemento na posio i
Requer o deslocamento direita dos elementos a(i+1)...a(n)
Begin
i:=1;
For j:=L.n+1 downto i do
L.A[j]:=L.A[j-1];
write (l.n+1,' valor...: ');
readln(l.A[i]);
L.n:=L.n+1;
End;

5) Remoo do i-simo elemento


Requer o deslocamento esquerda dos elementos a(i+1)...a(n)

ESTRUTURA DE DADOS PGINA 9

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Begin
i:=1;
for j:=i to L.n-1 do
L.A[j]:=L.A[j+1];
L.n:=L.n-1;
End;

ALGORITMOS DE BUSCA EM LES


1) LISTAS SEQUENCIAIS NO ORDENADAS
Seja L uma lista linear no ordenada alocada seqencialmente
Var
L: arrray [1..n] of record
chave: T1;
info: T2;
End;
A funo busca1 abaixo busca um registro contendo a chave x na lista L, e retorna o ndice do
registro se encontrado, caso contrrio retorna zero.
Function busca1(x);
Var i: 1..Max;
Begin
i := 1;
busca1 := 0; {elemento no encontrado}
While i <= Nelem do
If L[i].chave = x
then
Begin
busca1 := i;
i := Nelem + 1; {termina loop}
End
Else i := i+1;
End;
Em busca1( ), para cada elemento dois testes so realizados
1. i <= Nelem
2. L[i].chave = x.
Esse processo pode ser melhorado com o uso do seguinte artifcio: criado um novo registro
no final da lista, chamado de sentinela, que contm a chave procurada. A busca realizada
sabendo-se que um registro contendo a chave vai ser encontrado.
Ao final verifica se o registro encontrado o sentinela. Deste modo o teste duplo para cada
elemento evitado. A lista L, neste caso, deve poder conter um registro extra.
Function busca(x)
Var i: 1..Max;
Begin
L[Nelem+1].chave := x; {insere elemento sentinela}

ESTRUTURA DE DADOS PGINA 10

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

i := 1;
While (L[i].chave <> x) do
i := i+1;
{checa se encontrado o sentinela}
If (i = Nelem + 1)
Then
busca := 0
Else
busca := i;
End;
2) LISTAS SEQUENCIAIS ORDENADAS
No caso de listas ordenadas, deve-se aproveitar o fato de que nem sempre necessrio
percorrer a lista toda para concluirmos que elemento no est na lista.
A verso do algoritmo de busca com sentinela para listas ordenadas :
Function busca_ord(x)
Var
i: 1..Max;
Begin
L[Nelem+1] .chave := x; {insere elemento sentinela}
i := 1;
While (L[i].chave < x) do {compara-se apenas os menores}
i := i+1;
If (i = Nelem + 1) or i(L[i].chave <> x)
Then
busca := 0
Else
busca := i;
End;
O fato de se utilizar o recurso da sentinela na busca seqencial, acima, elimina a necessidade
de testar, para cada elemento, se o final da lista alcanado ou no.
No caso de listas ordenadas, pode-se apresentar um algoritmo BEM mais eficiente o qual
tira MUITO MAIS proveito do fato da lista estar ordenada!
O algoritmo de busca binria tem como idia bsica o fato de que, dada uma posio dentro
da lista, o elemento procurado vai estar ou antes ou depois desta posio, e, portanto, no se
precisa procurar dos dois lados.
Numa dada lista ordenada:
Compara-se o elemento procurado com o registro do meio da lista, para saber se o
elemento estaria na metade superior ou inferior da lista.
Repete-se esse processo at encontrar o elemento ou esgotar a lista.
Function busca_bin(x)
Var
inf, sup, meio: ndices;
Begin
inf := 1;

ESTRUTURA DE DADOS PGINA 11

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

sup := n;
busca_bin := 0;
While inf <= sup do
Begin
meio := [(inf + sup) div
If L[meio].chave = x
then
Begin
busca_bin :=
inf := sup +
End
Else If (L[meio].chave
Then
inf := meio
Else
sup := meio

2];

meio;
1;
< x)
+ 1
-1;

End;
End;

CRIAO DE BIBLIOTECAS
UNITS EM TURBO PASCAL
Uma Unit uma coleo de constantes, tipos de dados, variveis, procedimentos e funes.
Cada Unit como um programa Pascal separado. Ela uma biblioteca de declaraes que
permite dividir seu programa e compil-lo em partes separadas. Ela pode ter um corpo
principal o qual chamado antes do seu programa ser iniciado para preparar as
"inicializaes" necessrias.
Todas as declaraes em uma Unit esto normalmente relacionadas. Por exemplo, a unit CRT
contm todas as declaraes de rotinas relativas SCREEN do PC. O Turbo Pascal possui 8
Units pr-definidas: System, Overlay, Graph, Dos, Crt, Printer...
ESTRUTURA DE UMA UNIT
UNIT <identificador>; {arquivo deve ter mesmo nome.PAS}
INTERFACE
uses <lista de units> {opcional}
<declaraes pblicas> {s cabealho}
IMPLEMENTATION
uses <lista de units> {opcional}
<declaraes privadas>
<implementao de proc. e funes>
{corpo das funes e proc.}
Begin
<inicializaes>
End.
{ou}
End.
ESTRUTURA DE DADOS PGINA 12

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Exemplo 1: Unit IntLib


Contm duas rotinas simples atuando sobre os inteiros
Unit IntLib; /* INTLIB.PAS */
Interface
Procedure ISwap (var I,J: integer);
Function IMax(I,J: integer): integer;
Implementation
Procedure ISwap;
Var Temp: integer;
Begin
Temp:=I;
I:=J;
J:=Temp;
End;
Function IMax;
Begin
If I>J Then
IMax:=I
Else IMax:=J;
End;
End.
O programa abaixo, localizado em outro arquivo, utiliza esta unit.
Program Test;
Uses IntLib;
Var A,B: integer;
Begin
Write('D dois inteiros:');
Readln(A,B);
ISwap(A,B);
Writeln('A=',A, 'B=',B);
Writeln('Mx=', Imax(A,B));
End.
Exemplo 2: Unit circulares - Units podem "utilizar" outras Units estabelecendo referncias
"circulares". Program Circular: usa Unit Display (definida pelo usurio) para imprimir 3
mensagens na tela em coordenadas dadas.
Program Circular
Uses
Crt, Display;
Begin
Clrscr;
WriteXY(1,1,'upper left corner of screen');
WriteXY(100, 100, 'Way off the screen');
WriteXY(81-length('Back to reality'),15-length('Back to reality');
End.
ESTRUTURA DE DADOS PGINA 13

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

LISTA ESTTICA ENCADEADA LEE


Os elementos da lista so registros com um dos componentes destinado a guardar o endereo
do registro sucessor.
Vantagens:
no requer mais a movimentao de elementos na insero e eliminao (como na
lista seqencial);
apenas os ponteiros so alterados (lembre que cada registro pode conter elementos
muito complexos);
Desvantagens:
necessrio prever espao mximo da lista;
necessrio gerenciar a Dispo.
acesso no indexado, para acessar a(i) temos que percorrer a(1) ... a(i-1) pois o
endereo de a(i) est disponvel apenas em a(i-1);
aumento do tempo de execuo, o qual gasto obteno de espao de memria;
reserva de espao para a Dispo;
tamanho mximo pr-definido.
Quando usar:
quando for possvel fazer uma boa previso do espao utilizado e quando o ganho
dos movimentos sobre a perda do acesso direto a cada elemento for compensador.
Para evitar reservar espao e gerenciar a Dispo, podemos utilizar LISTAS ENCADEADAS
DINMICAS.

IMPLEMENTAO DE OPERAES LEE


Supondo apenas um campo de informao do tipo T:
Const N=_____; {nmero mximo de elementos}
Type
endereco=
0..N;
{elementos
armazenados
nas
posies
de
1 a N do array; o valor 0 indica fim da
lista}
Type
Rec = record
info: T
lig: endereo;
End;
Lista = record
A: array[1..N] of Rec;
Prim, Dispo: endereco;
End;
Var
L: lista;

ESTRUTURA DE DADOS PGINA 14

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

1) Qual o primeiro elemento da lista ?


Function Primeiro (L: lista): T;
Begin
If L.Prim <> 0
Then
Primeiro := L.A[L.Prim].info;
End;
2) Qual o ltimo ?
Function Ultimo(L: Lista): T;
Var
p: endereco;
Begin
If L.Prim = 0
Then
{Retorna lista vazia }
Else
Begin
p := L.Prim;
While L.A[p].lig <> 0 do
p
:=
L.A[p].lig;

{L.A[p].info
elemento}

ltimo

End;
Ultimo := L.A[p].info;
End;
3) Quantos elementos tem a lista ?
Function No_elementos(L: Lista): integer;
Var
Nelem: integer;
p: endereco;
Begin
If L.Prim = 0
Then
Nelem := 0 {lista vazia}
Else
Begin
p := L.Prim;
Nelem := 1;
While L.A[p].lig <> 0 do
Begin
Nelem := Nelem + 1; {Nelem contm o Nmero
de elementos}
p := L.A[p].lig;
End;
End;
No_elementos := Nelem;
End;
ESTRUTURA DE DADOS PGINA 15

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

ALGORITMOS PARA INSERO E ELIMINAO DE ELEMENTOS


Na insero podemos contar com o registro j como sendo disponvel, e na eliminao
podemos contar com o registro j como a ser deixado disponvel.
Para inserir ou eliminar um elemento da lista, temos que saber do endereo do predecessor
(lembre que a busca guiada pelo contedo do registro, no caso de listas ordenadas). Este
predecessor quem contm o endereo daquele que ser o sucessor do elemento
inserido/eliminado.
1) Insero aps o registro de endereo k
Procedure Insere(var L: Lista; k: endereco, valor: T);
Var
j: endereco;
Begin
If L.Dispo <> 0
Then {se a Dispo est vazia, no pode inserir!}
Begin
L.A[j].info := valor;
L.A[j].lig := L.A[k].lig;
L.A[k].lig := j;
End
Else {no pode inserir registro}
...
End;
2) Eliminao do registro de endereo j precedido por k
Procedure Remover(var L: Lista; k,j: endereco);
Begin
L.A[k].lig := L.A[j].lig;
End;
3) Casos especiais
Insero antes do primeiro elemento
Procedure Insere_prim(var L: Lista; valor: T);
Var
j: endereco;
Begin
If L.Dispo <> 0
Then
Begin
L.A[j].info:= valor;
L.A[j].lig := L.Prim;
L.Prim := j;
End
Else
{ no pode inserir }
End;
OBS: No caso da lista estar vazia, Prim passar a apontar o nico elemento da lista.

ESTRUTURA DE DADOS PGINA 16

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Insero em lista vazia


Procedure Insere_ListaVazia(var L: Lista; valor: T);
Var
j: endereco;
Begin
If L.Dispo <> 0
Then { lista vazia ou prim = 0 }
Begin
L.A[j].info:=valor;
L.A[j].lig:=0; {null}
L.Prim:=j;
End;
End;
Eliminao do primeiro elemento
Procedure Remove_Primeiro(var L: Lista);
Var
j: endereco;
Begin
j := L.Prim;
L.Prim := L.A[L.Prim].lig;
End;

LISTA DINMICA LD
As linguagens de programao modernas tornaram possvel explicitar no apenas o acesso
aos dados, mas tambm aos endereos desses dados.
Isso significa que ficou possvel a utilizao de ponteiros explicitamente implicando que uma
distino notacional deve existir entre os dados e as referncias (endereos) desses dados.
A notao introduzida por Wirth, com a introduo de Pascal, : Type Tp = ^T. Essa
declarao expressa que valores do tipo Tp so ponteiros para dados do tipo T. Portanto,
lemos o smbolo ^ como sendo ponteiro para... e na declarao acima lemos Tp um ponteiro
para variveis do tipo T.
O fato de que o tipo dos elementos apontados ser evidente na declarao do ponteiro tem
importncia fundamental. Isso distingue ponteiros de linguagens de alto nvel de endereos
em Assembly.
Valores para ponteiros so gerados quando dados correspondentes a seus tipos so
alocados/deslocados dinamicamente. Em Pascal, os procedimentos new e dispose existem
com esse propsito.
Portanto, deixa-se a cargo do programa (via linguagem de programao), e no do
programador, prover e devolver espao para inseres e eliminaes em tempo de execuo.

Custo: Tempo de execuo comprometido.


Idia: O programador declara apenas o tipo de registro que contm um elemento da
lista, e avisa que a alocao ser dinmica. Sempre que requisitar um registro novo

ESTRUTURA DE DADOS PGINA 17

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

para a insero, ou liberar um registro a ser eliminado, o programador lana mo de


duas rotinas pr-definidas para este fim.
At agora, quando queramos guardar muitos dados na memria, usvamos vetores. S que
vetores tm limite, ou seja, temos que definir de antemo o nmero mximo de elementos que
um vetor pode ter. O que acontece se no tivermos esse limite? Ou seja, o que fazemos se
esse limite no for definido? Uma alternativa seria criar um vetor imenso, gastando um mundo
de memria. Mas ainda assim correramos o risco de estourar o limite do vetor. Ento, o que
fazer?
A soluo ideal seria se pudssemos, medida que recebemos algum dado, separar um
espao na memria para ele e armazen-lo l. Ou seja, nosso limite seria dado pela
quantidade de memria disponvel no computador.
Naturalmente, como separamos um espao na memria e guardamos um valor l, temos que,
de algum modo, saber qual esse pedao de memria, ou seja, precisamos de uma espcie
de endereo que nos leve a esse pedao para que, futuramente, possamos acessar o que
guardamos l ou mesmo guardar algo l.
Ento como fazemos isso em Pascal? Com ponteiros. Ponteiros nada mais so do que
variveis que guardam o endereo de uma regio de memria, podendo essa regio conter a
informao que quisermos.
Vejamos como declaramos ponteiros em Pascal:
VAR nome_do_ponteir:^tipo_apontado;

Nesse caso, tipo_apontado qualquer tipo, simples ou definido pelo usurio, do Pascal. Ou
seja, no posso fazer:
VAR ptr : ^ARRAY[1..10] OF integer;

mas posso fazer:


TYPE vetor = ARRAY[1..10] OF integer;
VAR ptr : ^vetor;

Agora vamos ver como usar um ponteiro. Suponha a declarao:


VAR ptr : ^integer;

O que temos aqui? Apenas uma varivel, chamada ptr, que um ponteiro para um inteiro, ou
seja, ela guarda um endereo de memria onde pode ser armazenado um inteiro. Mas de qual
pedao ela tem o endereo? Nenhum. Para efetivamente dar um valor a ptr temos que fazer:
new(ptr);

A forma geral do new


New(varivel_de_ponteiro);

ESTRUTURA DE DADOS PGINA 18

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

O que, ento, isso faz? Esse comando simplesmente diz ao sistema operacional para que este separe
um pedao de memria em que caiba um inteiro (o tipo apontado por ptr), guardando o endereo deste
pedao em ptr. E qual esse endereo? No sabemos, e nem precisamos saber, pois o Pascal abstrai
tudo isso. Ou seja, podemos agora usar a varivel ptr quase como se fosse um integer comum. Por
que quase? Veja abaixo:
VAR ptr : ^integer;
BEGIN
new(ptr); {separei um pedao de memria para um
inteiro}
ptr^ := 2; {coloquei o valor 2 nesse pedao de
memria}
ptr^ := ptr^ * 3; {fao esse pedao de memoria
receber o triplo
do que l havia}
END.

Viu como fizemos? "ptr^" pode ser usada como qualquer varivel integer. Veja agora o programa
abaixo:
type
tipo=^integer;
VAR
p1 : tipo;
p2 : tipo;
BEGIN
clrscr;
new(p1); {reservei um pedao de memoria para um inteiro,
fazendo p1 apontar para ele}
p2 := p1; {fiz p2 apontar para o mesmo pedao de memoria
que p1 aponta}
p1^ := 4; {coloquei o valor 4 nesse pedao de memoria}
writeln(p2^); {escrevi o valor que est no pedao de
memria apontado por p2, ou seja, 4, pois
p2 aponta para o mesmo pedao de memria
que p1}
p2^ := p2^ + 3; {adicionei 3 ao valor que havia no pedao
de memria apontado por p2 e armazenei
novamente nesse pedao o resultado}
writeln(p1^); {escrevo o contedo da memria apontada por
p1, ou seja, 7, pois p1 aponta para o mesmo
pedao de memria que p2 aponta}
readkey;
END.

ESTRUTURA DE DADOS PGINA 19

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Como isso funciona? Vejamos por partes:


Quando fizemos new(p1), separamos (ou, como dizemos, alocamos) espao na memria
suficiente para um inteiro, guardando o endereo desse espao em p1, ou seja, fizemos p1
apontar para l:

Ao fazer p2 := p1 (note que no p2^ := p1^), guardamos uma cpia do endereo que
estava em p1 em p2. Ou seja, fazemos p2 apontar para a mesma regio de memria
que p1 apontava:

Ao fazermos p1^ := 4 guardamos 4 nessa regio:

Ao lermos p2^ no write, simplesmente lemos o valor que est na regio da memria
apontada por p2, ou seja, 4.

Ao fazermos p2^ := p2^ + 3, pegamos o contedo da regio de memria apontada por


p2, somamos 3 a este e armazenamos o resultado de volta nessa mesma regio:

Ao lermos p1^ no write, novamente lemos o valor que est na regio de memria
apontada por p1, ou seja, 7, j que esta a mesma regio que apontada por p2 e que
foi modificada no passo anterior.

Ento no confunda! Se fazemos


p2^ := p1^;

estamos copiando o contedo da regio de memria apontada por p1 para a regio de memria apontada
por p2. J se fizermos
p2 := p1;

estaremos fazendo p2 apontar para a mesma regio de memria apontada por p1. Agora que sabemos
como carregar valores com ponteiros, como fazemos para "zerar" um ponteiro? Ou seja, para dizer que
ele no aponta para lugar nenhum?
p1 := NIL;

ESTRUTURA DE DADOS PGINA 20

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Se no fizermos isso, ele conter um endereo de memria que pode j ter sido liberada pelo programa,
ou que pode no pertencer ao programa, o que geraria um erro quando da execuo.
E, por falar em liberar memria, como fazemos se quisermos liberar a memria que reservamos com
new?
Dispose(varivel_de_ponteiro);

ou seja
Dispose(p1);

Dispose avisa ao sistema operacional que no vamos mais precisar desse pedao de memria, liberando
esta. SEMPRE libere a memria que no vai mais usar para no esgotar os recursos da mquina.
Cuidado com o seguinte erro:
type
tipo=^integer;
VAR p1 : tipo;
p2 : tipo;
BEGIN
new(p1);
p2 := p1;
p1^ := 4;
Dispose(p2);
writeln(p1^)
END.

isso pode gerar um erro, pois j liberei a memria apontada por p2, que a mesma apontada por p1
Vale tambm lembrar que, ao final do programa, se voc no liberou a memria usada, o computador a
libera para voc. Ainda assim uma boa prtica limpar seu lixo.
E se agora quisermos um ponteiro para um tipo mais complexo, como registro?
TYPE
Tipo1=real;
Tipo2=integer;
Reg = RECORD
cp1 : tipo1;
cp2 : tipo2;
cp3 : ARRAY[1..10] of char
END;
VAR p : ^reg;
BEGIN
New(p);
END.

ESTRUTURA DE DADOS PGINA 21

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
Pronto! Aloquei espao para o meu registro. Ou seja, na memria foi reservado espao suficiente para guardar os 3 campos
do nosso registro. E como acessamos ou mudamos o valor desses campos?
TYPE
Tipo1=real;
Tipo2=integer;
Reg = RECORD
cp1 : tipo1;
cp2 : tipo2;
cp3 : ARRAY[1..10] of char
END;
VAR p : ^reg;
i : integer;
BEGIN
new(p);
p^.cp1 := 3.12;
p^.cp2 := Round(p^.cp1); {guardei 3}
FOR i:=1 TO 10 DO
p^.cp3[i] := Chr(Ord('a') + i);
writeln(p^.cpq,' - ', p^.cp2,' ',p^.cp3[5]);
Dispose(p)
END.
Ou seja, agimos como se "p^" fosse o nome do registro. E se em vez de registro quisermos lidar com um vetor?
TYPE
pvet=^vet;
vet = ARRAY[1..10] of integer;
VAR p : pvet;
BEGIN
clrscr;
new(p);
p^[1] := 4;
p^[2] := 10;
p^[3] := p^[1] + p^[2];
writeln(p^[1],' + ',p^[2],' =
',p^[3]);
Dispose(p);
writeln(p^[3]);
readkey;
END.

Novamente, agimos como se "p^" fosse o nome do vetor.


Com ponteiros, as operaes permitidas so = e <>. Assim ,no posso fazer +, - etc. Ou seja, as nicas
operaes que posso usar com ponteiros so:
p1 = p2
p1 <> p2

->
->

True se ambos apontam para a mesma regio de memria


True se ambos apontam para regies diferentes

ESTRUTURA DE DADOS PGINA 22

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Agora que j vimos o que so ponteiros, vamos aprender, na prxima seo, a us-los.

ESTRUTURA DE DADOS (ED) E OPERAES LD


LISTA DINMICA ENCADEADA
Suponha que queremos ler uma lista de dados. At a tudo bem. Agora suponha que no
conhecemos o nmero total de dados. Como fazemos ento?
Seria desejvel seguir o seguinte algoritmo:
inicialmente a lista est vazia
enquanto o usurio no manda parar de ler
leio um dado
coloco este dado na lista

assim fica fcil no? Mas como fazer isso em Pascal? Usando ponteiros. Como? Com uma
lista encadeada. O que, ento, uma lsita encadeada?
Uma lista encadeada uma lista onde cada elemento - chamado de n - contm um valor e
um ponteiro para o elemento seguinte. Assim, sabendo onde est o primeiro elemento da lista,
podemos chegar a qualquer outro elemento. H vrios tipos de listas encadeadas:

Simples:

O sinal de aterramento significa que este ponteiro NIL, ou seja, no aponta para lugar
nenhum.

Circular:

ESTRUTURA DE DADOS PGINA 23

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Duplamente encadeada:

e muitas outras mais. O limitante apenas sua imaginao. Aqui iremos usar somente listas
simples. Mas e qual as vantagens e desvantagens de cada uma? Listas duplamente
encadeadas so fceis de se percorrer, mas ocupam mais espao na memria. Note que
nessas eu posso, a partir de um elemento, voltar na lista, percorr-la de trs para frente, pois
tenho ponteiros que medizem onde esto o prximo elemento e o anterior.
As circulares simples so fceis de percorrer e no ocupam muita memria. Mas se o nmero
de elementos for grande, vai se comportar quase como uma lista simples. Qual lista a
melhor? Depende do problema a ser resolvido.,p> Agora vamos definir operaes bsicas em
listas:

Criao de uma lista

Incluso de um elemento na lista

Excluso de um elemento da lista

Esvaziamento da lista

Contagem do nmero de elementos da lista

Incluso de um elemento na posio i

Excluso do i elemento na lista

Busca da posio do primeiro elemento de valor x

Excluso do primeiro elemento de valor x

etc

Vamos ver ento como criar uma lista encadeada. Nos exemplos que seguem estaremos
usando a lista encadeada simples, conforme foi apresentada acima.
Antes de mais nada, vamos definir nossa lista:
TYPE tipo = real;
p_no = ^no;
no
= RECORD
valor : tipo;
prox : p_no
END;

Agora vamos definir o procedimento de criao da lista.


PROCEDURE Cria(VAR cabeca : p_no);
BEGIN
cabeca := NIL
END;

ESTRUTURA DE DADOS PGINA 24

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Pronto! O que fizemos com isso? Dissemos que a lista est vazia ao darmos um valor "nada"
cabea desta. Se no fizermos isso, a cabea pode conter lixo indesejvel.
Agora vamos incluir um elemento na lista. A questo : onde? Voc decide. Pode ser no
incio, pode ser no meio (caso voc queira ordenar a lista enquanto a constri) e pode ser no
fim. Nesse caso, vamos por no fim. Ento, como faremos?
Suponha que temos a seguinte lista:

Vamos, ento, colocar um elemento em seu final

Alocamos o espao para o novo elemento, fazendo q apontar para ele, e o


abastecemos com valor

Usamos um ponteiro auxiliar, p, para apontar para a cabea da lista

Percorremos a lista com p at que este aponte para o ltimo elemento

Fazemos o prximo elemento de p (que agora aponta para o fim da lista) ser q, ou seja,
fazemos q ser o novo fim da lista

E se a lista estiver inicialmente vazia? Ento

ESTRUTURA DE DADOS PGINA 25

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Alocamos o espao para o novo elemento e o abastecemos com valor

Fazemos a cabea da lista ser esse novo elemento

Assim, o procedimento fica:

ESTRUTURA DE DADOS PGINA 26

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

PROCEDURE Inclui(VAR cabeca : p_no; elemento : tipo);


VAR q : p_no; {o novo elemento}
p : p_no; {auxiliar}
BEGIN
{aloco espao para o novo elemento}
New(q);
{abasteo os valores nesse}
q^.valor := elemento;
q^.prox := NIL;
{vejo onde coloco q na lista}
IF cabeca <> NIL THEN
BEGIN
{a lista no estava vazia}
p := cabeca;
{vou at o fim da lista}
WHILE p^.prox <> NIL DO p := p^.prox;
{agora p o ltimo elemento, pois p^.prox = NIL}
{fao o prximo elemento de p ser q, ou seja, q o
novo fim}
p^.prox := q
END
ELSE {a lista est vazia. Fao q ser a cabea}
cabeca := q
END;

Vamos agora excluir um elemento da lista. Novamente, qual? Voc escolhe! Vamos tomar
como poltica a excluso do primeiro elemento da lista. Como faremos isso?
Suponha a lista:

Vamos, ento, retirar um elemento de seu incio:

Primeiro fazemos p apontar para o incio da lista:

ESTRUTURA DE DADOS PGINA 27

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Depois fazemos a cabea apontar para o segundo elemento:

Eliminamos agora o elemento apontado por p

E o procedimento fica:
PROCEDURE Exclui(VAR cabeca : p_no; VAR
valor:tipo);
VAR p : p_no; {auxiliar}
BEGIN
IF cabeca <> NIL THEN
BEGIN
{a lista no est vazia}
p := cabeca;
{fao a cabea apontar para o prximo}
cabeca := cabeca^.prox;
{retorno o valor que est em p}
valor := p^.valor;
{mato o elemento apontado por p}
Dispose(p);
END
{else a lista est vazia, no h o que tirar}
END;

Suponha que queremos simplesmente matar a lista inteira, como fazemos isso? Da mesma
forma que exclumos um elemento, s que no devolvemos valor algum:

Coloco um ponteiro p na cabea da lista

Enquanto p no for nil


o

Fao a cabea apontar para o prximo de p

Mato p

Fao p apontar para a cabea

O procedimento fica:

ESTRUTURA DE DADOS PGINA 28

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

PROCEDURE Limpa(VAR cabeca : p_no);


VAR p : p_no; {auxiliar}
BEGIN
p := cabeca;
WHILE p <> NIL DO
BEGIN
cab := p^.prox;
Dispose(p);
p := cab
END
END;

E como fazemos para contar os elementos de uma lista? Basta criar um contador e percorrer
a lista incrementando o contador:

Coloco um ponteiro p na cabea da lista e zero o contador cont

Enquanto p no for nil


o

Incremento cont

Fao p apontar para o prximo elemento

Ou seja:
FUNCTION NumEl(cabeca : p_no) : integer;
VAR p : p_no; {auxiliar}
BEGIN
p := cabeca;
NumEl := 0;
WHILE p <> NIL DO
BEGIN
p := p^.prox;
NumEl := NumEl + 1
END
END;

Agora, usando algumas das funes acima, vamos incluir um novo n na posio i da nossa
lista. Como faremos isso? Suponha a seguinte lista

Primeiro fazemos p apontar para o incio da lista:

ESTRUTURA DE DADOS PGINA 29

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Em seguida movemos p at o elemento anterior posio em que queremos incluir


(suponha que queremos incluir na 3 posio):

Criamos, ento, espao para o novo elemento, fazendo q apontar para ele:

Fazemos, ento, o prximo elemento de q ser o prximo de p:

E o prximo elemento de p ser q:

pronto! Inclumos na posio i = 3.


E se quisermos incluir na ltima posio? Funciona? Claro! Pois pararei com p no ltimo
elemento.
E se a lista estiver vazia? Nesse caso, basta criar o elemento e fazer a cabea apontar para
ele (veja abaixo como incluir na primeira posio). Note que nesse caso, o nico i aceitvel
1.
E se a posio pedida for 1? Esse um caso um pouco mais complicado, pois no h como
parar um elemento antes, o que indica que nosso algoritmo falha. Como fazer, ento?

Primeiro criamos espao para o novo elemento, fazendo q apontar para ele:

ESTRUTURA DE DADOS PGINA 30

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Fazemos, ento, o prximo elemento de q ser a cabea:

E a cabea apontar para q:

Pronto! Inclumos na primeira posio.


Vamos agora ao procedimento:

ESTRUTURA DE DADOS PGINA 31

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
PROCEDURE IncluiEmPos(VAR cabeca:p_no;valor:tipo;posicao:integer);
VAR p : p_no;
{auxiliar}
q : p_no;
{o novo elemento}
i : integer; {contador do FOR}
BEGIN
{testo se a posio vlida}
IF (posicao <= (NumEl(cabeca) + 1)) AND (posicao > 0) THEN
BEGIN
{ uma posio vlida. O +1 porque se tem 5 elementos
posso por na posio 6, por exemplo (embora no na 7)}
{crio o novo elemento}
new(q);
q^.valor := valor;
q^.prox := NIL;
IF posicao=1 THEN {quero na primeira posio}
BEGIN
{se a lista estiver vazia, no h problema aqui}
{fao o prximo de q ser a cabea}
q^.prox := cabeca;
{fao a cabea ser q}
cabeca := q
END
ELSE BEGIN { outra posio}
{note que aqui a lista jamais estar vazia, seno
NumEl retornaria 0 e posio > 1}
{fao p apontar para a cabea}
p := cabeca;
{movo p at o elemento anterior posio. Como p j
est em 1, movo posicao-2 posies}
FOR i:=1 TO posicao-2 DO
p := p^.prox;
{agora p aponta para o elemento anterior}
{fao o prximo de q ser o prximo de p}
q^.prox := p^.prox;
{fao o prximo de p ser q}
p^.prox := q
END
END
{ELSE no faz nada!}
END;

ESTRUTURA DE DADOS PGINA 32

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

timo! Vamos agora excluir um elemento da posio i. Suponha a seguinte lista:

Primeiro fazemos p apontar para o incio da lista:

Em seguida movemos p at o elemento anterior posio do elemento que queremos


excluir (suponha que queremos excluir da 3 posio):

Marcamos a posio a ser excluda com um ponteiro q:

Fazemos, ento, o prximo elemento de p ser o prximo de q:

Eliminamos q:

pronto! Exclumos o n da posio i = 3.


E se a lista estiver vazia? Nesse caso, Nada poder ser excludo.

ESTRUTURA DE DADOS PGINA 33

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

E se a posio pedida for 1? Esse, novamente, um caso um pouco mais complicado, pois no h
como parar um elemento antes, o que indica que nosso algoritmo falha. Como fazer, ento? Basta
seguir o algoritmo dado acima para retirar um elemento do incio da lista.
Vamos, ento, funo que retira o 1 elemento da lista. Essa funo retorna o valor que estava nesse
elemento:

FUNCTION TiraDaPos(VAR cabeca:p_no;posicao:integer):tipo;


VAR p : p_no;
{auxiliar}
q : p_no;
{auxiliar}
i : integer; {contador do FOR}
BEGIN
{testo se a posio vlida}
IF (posicao <= NumEl(cabeca)) AND (posicao > 0) THEN
BEGIN
{ uma posio vlida. Note que se a lista estiver vazia
nada feito, pois posicao >=1, o que > 0}
{fao p apontar para a cabea}
p := cabeca;
IF posicao=1 THEN {quero na primeira posio}
BEGIN
{fao a cabea ser o segundo elemento}
cabeca := cabeca^.prox;
{dou o valor de retorno}
TiraDaPos := p^.valor;
{mato o n}
Dispose(p)
END
ELSE BEGIN { outra posio}
{movo p at o elemento anterior posio. Como p j
est em 1, movo posicao-2 posies}
FOR i:=1 TO posicao-2 DO
p := p^.prox;
{agora p aponta para o elemento anterior}
{fao o prximo de p ser q}
q := p^.prox;
{fao o prximo de p ser o prximo de q}
p^.prox := q^.prox;
{retorno o valor de q}
TiraDaPos := q^.valor;
{mato o n apontado por q}
Dispose(q)
END
END
END;

ESTRUTURA DE DADOS PGINA 34

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Agora vamos ver como buscar a posio do primeiro elemento que contenha o valor x na
nossa lista. Para tal, o procedimento simples:

Coloco um ponteiro p na cabea da lista e crio um contador, inicializando-o com 1.

Enquanto p no for NIL e no encontrei o valor vou incrementando p e o contador.

Se encontrei o valor, retorno o valor do contador, seno, retorno 0.

Vamos, ento, funo:

FUNCTION Pos(cabeca:p_no; elemento:tipo):integer;


VAR p : p_no;
{auxiliar}
BEGIN
{inicializo o contador}
Pos := 1;
{aponto p para a cabea da lista}
p := cabea;
WHILE (p <> NIL) AND (p^.valor <> elemento) DO
BEGIN
p := p^.prox;
Pos := Pos+1
END;
IF p = NIL THEN Pos := 0
{o else automtico, pos ter o valor certo}
END;

E para excluir o primeiro elemento de valor x? Basta

Buscar a posio do primeiro elemento de valor x

Excluir o elemento nessa posio

Ou seja:
PROCEDURE ExcluiX(VAR cabeca:p_no; elemento:tipo);
VAR el : tipo; {o elemento a ser excludo, auxiliar}
BEGIN
el := TiraDaPos(cabeca,Pos(cabeca,elemento))
{exclu, el jogo fora}
END;

ESTRUTURA DE DADOS PGINA 35

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

PILHAS
Uma PILHA um tipo especial de LISTA LINEAR em que todas as operaes de insero e
remoo so realizadas numa mesma extremidade, denominada TOPO.
Cada vez que um novo elemento deve ser inserido na pilha, ele colocado no topo; e em
qualquer momento, apenas aquele posicionado no topo da pilha pode ser removido. Devido a
esse tipo de acesso, os elementos so sempre removidos numa ordem inversa quela em que
foram inseridos, de modo que o ltimo elemento que entra exatamente o primeiro que sai.
Por isso essas listas so denominadas LIFO (last-in/first-out).
Uma LISTA LIFO, uma coleo que pode aumentar ou diminuir durante a sua existncia.
Pilha sinnimo de Lista LIFO.
Exemplo: Pilha de pratos.
Uma pilha suporta trs operaes bsicas, tradicionalmente denominadas como:
Topo: Acessa o elemento posicionado no topo da pilha;
Push: Insere um novo elemento no topo da pilha (Insere);
Pop: Remove um elemento do topo da pilha (Retira ou Elimina).
Sendo P uma pilha e x um elemento qualquer, a operao push(P,x) aumenta o tamanho da
pilha P, acrescentando o elemento x no seu topo. A operao Pop(P) faz com que a pilha
diminua, removendo e retornando o elemento no seu topo. Das trs operaes bsicas, a
nica que no altera o estado da pilha Top(P); ela simplesmente retorna uma cpia do
elemento existente no topo da pilha, sem removlo.
OPERAO
--Push (P,a)
Push (P,b)
Push (P,c)
Pop (P)
Pop (P)
Push (P,d)
Top (P)

ESTADO DA PILHA
P: [ ]
P: [a]
P: [b,a]
P: [c,b,a]
P: [b,a]
P: [a]
P: [d,a]
P: [d,a]

RESULTADO
--------c
b
--d

Tomando como exemplo um porta guardanapos, existem as operaes push (empurre). Ao


inserir um elemento, os outros so empurrados para baixo e o ltimo elemento mantido no
topo da pilha, da o nome push-down. Analogamente ao remover um elemento, como se os
demais pressionassem por baixo at que ele saltasse, pop-up (saltar para cima).
Notao Linear de uma Pilha:

P: [an, an-1, ..., a2, a1]


Notao grfica:

ESTRUTURA DE DADOS PGINA 36

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

an
an-1
...
a2
a1

Final

Comeo

Exemplo limitaes fsicas de uma pilha (cho, mesa, prato, teto, altura da parede)
Precisamos ento de mais trs operaes essenciais para manipular pilhas:
Init: Inicializa a pilha no estado vazia;
IsEmpty: verifica se a pilha est vazia;
IsFull: verifica se a pilha est cheia.
Init(P), IsEmpty(P), IsFull(P).
Exemplos do uso de pilhas:
1. Programa para converter de decimal para binrio.
2. Chamadas e retornos de rotinas em um programa, cujo papel da pilha fundamental
no controle do programa.

PILHAS COM ALOCAO ESTTICA:


ESTRUTURA DE DADOS
const
MAX = 50; {qtd elementos}
type
elem = char;
pilha = record
topo :integer;
memo :array[1..MAX] of elem;
end;
var
p :pilha;

ALGORITMOS PARA MANIPULAO


INICIALIZANDO A PILHA
procedure init(var p:pilha);
begin
p.topo := 0;
end;
VERIFICANDO LIMITES (VAZIA OU CHEIA)
Function EstaVazia(p:pilha):boolean;
ESTRUTURA DE DADOS PGINA 37

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Begin
If p.topo = 0
then
EstaVazia := true
Else
EstaVazia := false;
end;
Function EstaVazia(p:pilha):boolean;
Begin
EstaVazia := (p.topo=0)
End;
Function EstaCheia(p:pilha):boolean;
Begin
If p.topo = MAX
then
EstaCheia := true
Else
EstaCheia := false;
end;
function EstaCheia(p:pilha):boolean;
begin
EstaCheia := (p.topo=MAX)
end;
EMPILHANDO UM ELEMENTO
procedure push(var p:pilha); x:elem);
begin
if (not EstaCheia(p)
then
begin
p.topo := p.topo+1;
p.memo[p.topo] := x;
end
else
writeln('Estouro de pilha!');
end;
DESEMPILHANDO UM ELEMENTO
function pop(var p:pilha):elem;
begin
if not EstaVazia(p)
then
begin
pop := p.memo[p.topo];
p.topo := p.topo-1;
ESTRUTURA DE DADOS PGINA 38

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

end;
else
writeln('Pilha vazia');
end;
OBTENDO O VALOR DO TOPO
function top(p:pilha):elem;
begin
if not EstaVazia(p)
then
top := p.memo[p.topo];
else
writeln('Pilha vazia!);
end;

Pilha de Alocao Dinmica


Pense numa pilha de livros. assim que ela funciona. Se queremos por mais um livro na
pilha, onde colocamos? No topo! E se queremos tirar um livro, de onde tiramos? Do topo.
Ento, como temos visto, uma pilha nada mais do que uma lista encadeada que tem como
caracterstica o fato de que, se queremos incluir um elemento na lista, temos de inclu-lo no
incio desta, e se queremos tirar um elemento da lista, tiramos do incio desta.
Dessa forma, uma pilha tem as seguintes funes:

Criao da pilha (como nas listas acima)

Empilhamento (quando coloco um elemento no topo da pilha, ou seja, no incio da lista)

Desempilhamento (quando tiro um elemento do topo da pilha, ou seja, do incio da lista)

Note que no h como eu tirar um elemento do meio da pilha.


como nossa pilha de livros, para retirar um livro do meio, tenho que desempilhar todos os
que esto acima. Da mesma forma, para tirar um dado do meio da pilha, tenho que
desempilhar os que esto antes dele. Vejamos, agora, funes para criao, empilhamento e
desempilhamento:
TYPE tipo
= real;
p_pilha = ^pilha;
pilha
= RECORD
dado : tipo;
prox : p_pilha
END;
VAR topo : p_pilha;
PROCEDURE IniciaPilha(VAR topo : p_pilha);
BEGIN
topo := NIL
END;

ESTRUTURA DE DADOS PGINA 39

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
PROCEDURE Empilha(VAR topo : p_pilha; dado : tipo);
VAR p : p_pilha; {auxiliar}
BEGIN
{crio o novo elemento e dou valor a ele}
new(p);
p^.valor := dado;
{fao ele apontar para o topo da pilha}
p^.prox := topo;
{fao o topo apontar para ele}
topo := p
END;
FUNCTION Desempilha(VAR topo : p_pilha) : tipo;
VAR p : p_pilha; {auxiliar}
BEGIN
{fao p apontar para o topo}
p := topo;
{retorno o valor de p}
Desempilha := p^.valor;
{baixo o topo, para o segundo elemento}
topo := topo^.prox;
{elimino p}
Dispose(p)
END;

FILAS
Uma FILA um tipo especial de LISTA LINEAR em que as inseres so realizadas num
extremo, ficando as remoes restritas ao outro. O extremo onde os elementos so inseridos
denominado final e, aquele de onde so removidos denominado comeo da fila.
A cada insero, um novo elemento colocado no final da fila. O elemento que aguarda mais
tempo na fila, o do comeo, o removido por primeiro. A ordem de sada corresponde
diretamente ordem de entrada, ou seja, os primeiros que entram so os primeiros que saem.
Graas a isso, as filas so denominadas listas FIFO (First-In/First- Out).
Exemplo bastante comum: balco de atendimento, onde pessoas formam fila para
aguardarem atendimento. No devemos considerar pessoas que furam a fila, pois o tipo
abstrato de dados no suporta insero nem remoo no meio da lista.

Sai

Comeo

Final

Entra

Fila em ingls, significa queue. Duas operaes bsicas que uma fila suporta so:

ESTRUTURA DE DADOS PGINA 40

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Enqueue: insere um elemento no final da fila;


Dequeue: remove um elemento do comeo da fila.
Sendo F uma fila e x um elemento qualquer, a operao Enqueue(F,x) aumenta o tamanho
da fila F, acrescentando x ao seu final. A operao dequeue(F) faz a fila diminuir, j que
remove e retorna o elemento posicionado no comeo.
OPERAO
--Enqueue(F,a)
Enqueue(F,b)
Enqueue(F,c)
Enqueue(F,d)
Dequeue(F)
Dequeue(F)
Enqueue(F,e)
Enqueue(F,f)
Enqueue(F, Dequeue(F))
Dequeue(F)
Dequeue(F)
Dequeue(F)

F:
F:
F:
F:
F:
F:
F:
F:
F:
F:
F:
F:
F:
F:

ESTADO DA FILA
[]
[a]
[a,b]
[a,b,c]
[a,b,c,d]
[b,c,d]
[c,d]
[c,d,e]
[c,d,e,f]
[d,e,f]
[d,e,f,c]
[e,f,c]
[f,c]
[c]

RESULTADO
----------a
b
----c
--d
e
f

Notao Linear de uma Fila:

F: [a1, a2..., an-1, an]


Notao grfica:
Comeo
a1

Final
a2

...

an-1

an

Precisamos ento de mais operaes essenciais para manipular filas:


Init: Inicializa a fila no estado vazia;
Vazia: verifica se a fila est vazia;
Cheia: verifica se a fila est cheia; (quando for esttica!).
Init(F), Vazia(F), Cheia(F).
Tipo de Alocao:

ESTRUTURA DE DADOS PGINA 41

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

Esttica: utilizamos com estruturas de registro com vetor para armazenar os


elementos da fila;
Dinmica: utilizamos com estruturas de ponteiros para registros com elemento e
endereo de ligao do tipo ponteiro.
Exemplos do uso de filas:
Escalonamento de JOBs. Fila de processos aguardando os recursos do Sistema
Operacional.

FILA COM ALOCAO ESTTICA


unit filaest; {arquivo filaest.pas}
INTERFACE
const
MAX = 50;
type
elem = char;
fila = record
comeco :integer;
final :integer;
memo :array[1..MAX] of elem;
end;
procedure init(var f:fila);
function vazia(f:fila):boolean;
function cheia(f:fila):boolean;
function prim (f: fila): elem;
procedure enqueue(var f:fila; x:elem);
function dequeue(var f:fila):elem;
IMPLEMENTATION
procedure init(var f:fila);
begin
f.comeco := 1;
f.final := 1;
end;
function vazia(f:fila):boolean;
begin
vazia := (f.comeco = f.final);
end;
function cheia(f:fila):boolean;
begin
cheia := (f.final>MAX);
end;
function prim (f: fila): elem;
Begin
prim := f.memo[f.comeco];
End;
procedure enqueue(var f:fila; x:elem);
begin

ESTRUTURA DE DADOS PGINA 42

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

if not cheia(f)
then
begin
f.memo[f.final] := x;
f.final := f.final+1;
end
else
writeln('Fila cheia!');
end;
function dequeue(var f:fila):elem;
begin
if not vazia(f)
then
begin
dequeue := f.memo[f.comeco];
f.comeco := f.comeco+1;
end
else
writeln('Fila vazia!');
end;
begin
end.
EXEMPLO DO PROGRAMA PRINCIPAL QUE UTILIZA A BIBLIOTECA:
program fila_tst;
uses crt,filaest;
var
minhafila:fila;
elemento :elem;
c :char;
begin
clrscr;
init(minhafila);
write('digite elemento: ');
readln(elemento);
while (elemento<>' ') do
begin
enqueue(minhafila,elemento);
write('digite elemento: ');
readln(elemento);
end;
while not vazia(minhafila) do
begin
elemento := dequeue(minhafila);
write(elemento);
end;
writeln(pressione uma tecla...);
c := readkey;
end.

ESTRUTURA DE DADOS PGINA 43

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

FILA COM ALOCAO DINMICA


PROGRAMA PRINCIPAL UTILIZANDO A BIBLIOTECA:
program fila_tst;
uses crt,fdinlib;
var
minhafila :fila;
elemento :elem;
c :char;
begin
clrscr;
init(minhafila);
write('digite elemento: ');
readln(elemento);
while (elemento<>' ') do
begin
enqueue(minhafila,elemento);
write('digite elemento: ');
readln(elemento);
end;
while not vazia(minhafila) do
begin
elemento := dequeue(minhafila);
write(elemento);
end;
writeln(pressione uma tecla...);
c := readkey;
end.
BIBLIOTECA DE FILA DINMICA:
unit fdinlib; {fdinlib.pas}
INTERFACE
type
elem = char;
p_no = ^reg_no;
reg_no = record
valor :elem;
prox :p_no;
end;
fila = record
comeco :p_no;
final :p_no;
end;
procedure init (var f: fila);
function vazia (f:fila): boolean;
function prim (f:fila): elem;
procedure enqueue (var f:fila; x: elem);

ESTRUTURA DE DADOS PGINA 44

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

function dequeue (var f: fila): elem;


IMPLEMENTATION
procedure init (var f: fila);
Begin
f.comeco := nil;
f.final := nil;
End;
function vazia (f:fila): boolean;
Begin
vazia := ( f.comeco = nil) and (f.final = nil);
End;
function prim (f:fila): elem;
Begin
prim := f.comeco^.valor;
End;
procedure enqueue (var f:fila; x: elem);
var
pont :p_no;
Begin
if vazia(f)
then
begin
new(pont);
f.final := pont;
f.final^.valor := x;
f.final^.prox := nil;
f.comeco := f.final;
end
else
begin
new(pont);
f.final^.prox := pont;
pont^.valor := x;
pont^.prox := nil;
f.final := pont;
end;
End;
function dequeue (var f: fila): elem;
var
pont :p_no;
Begin
if not vazia(f)
then
begin
dequeue := f.comeco^.valor;
if f.comeco^.prox = nil
then
begin
dispose(f.comeco);
f.comeco := nil;
ESTRUTURA DE DADOS PGINA 45

CENTRO EDUCACIONAL FUCAPI


CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS

f.final := nil;
end
else
begin
pont := f.comeco^.prox;
dispose(f.comeco);
f.comeco := pont;
end;
end
else
writeln('Fila Vazia!');
End;
begin
end.

Referncias:
Algoritmos e Estrutura de Dados
Wirth, Niklaus
LTC
Estrutura de Dados e Algoritmos
Preiss, Bruno R.
Campus
Lgica de Programao e Estrutura de Dados
Sandra Puga & Gerson Rissetti
Prentice-hall
Algoritmos e Programao de Computadores
Norton Trevisan Roman

ESTRUTURA DE DADOS PGINA 46