apostila estrutura de dados.pdf
TRANSCRIPT
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 1
APOSTILA
ESTRUTURA DE DADOS
MANAUS 2013
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 2
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 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.
processamento de dados Exemplo:
ENTRADA (Estado Inicial)
PROCESSAMENTO SADA (Estado Final)
DADOS CONHECIMENTO INFORMAO
Raio R de uma circunferncia
P = 2 . . R Permetro P da circunferncia
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 3
TIPOS ABSTRATOS DE DADOS OBJETIVOS DAS ESTRUTURAS DE DADOS TIPOS DE DADOS (TDS) 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 DADOS (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.
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 4
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 DADOS (EDS) 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.
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 baseia-se 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
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 5
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:
SEQENCIAL ENCADEADA ESTTICA Esttica Seqencial Esttica Encadeada DINMICA Dinmica Seqencial Dinmica Encadeada
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 6
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. 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.
Memria usada pelo programa P:
1FFAh Memria livre no sistema
ESTTICA DINMICA
1FFAh 12345
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 7
ALOCAO SEQENCIAL X ALOCAO ENCADEADA ALOCAO SEQENCIAL: Consiste em colocar os elementos de uma lista em clulas de memria consecutivas, um aps o outro. 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,
Clula
Memria
elemento
A1 1C34h A2 1725h A3
3FAAh 1C34h 1725h
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 8
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.
A a1 a2 an 1 2 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.
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 9
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)
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 10
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
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 11
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;
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 12
sup := n; busca_bin := 0;
While inf
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 13
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.
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 14
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;
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 15
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 o ltimo
elemento} 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;
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 16
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.
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 17
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
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 18
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);
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 19
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.
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 20
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;
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 21
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.
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 22
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 -> True se ambos apontam para a mesma regio de memria p1 p2 -> True se ambos apontam para regies diferentes
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 23
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:
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 24
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;
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 25
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
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 26
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:
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 27
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:
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 28
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
o Mato p
o Fao p apontar para a cabea O procedimento fica:
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 29
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
o 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:
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 30
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:
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 31
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:
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 32
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 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;
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 33
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.
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 34
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 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;
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 35
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;
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 36
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 ESTADO DA PILHA RESULTADO --- P: [ ] --- Push (P,a) P: [a] --- Push (P,b) P: [b,a] --- Push (P,c) P: [c,b,a] --- Pop (P) P: [b,a] c Pop (P) P: [a] b Push (P,d) P: [d,a] --- Top (P) P: [d,a] 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:
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 37
an Final an-1 ... a2 a1 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;
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 38
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;
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 39
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;
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 40
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.
Comeo Final
Sai Entra Fila em ingls, significa queue. Duas operaes bsicas que uma fila suporta so:
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 41
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 ESTADO DA FILA RESULTADO --- F: [ ] --- Enqueue(F,a) F: [a] --- Enqueue(F,b) F: [a,b] --- Enqueue(F,c) F: [a,b,c] --- Enqueue(F,d) F: [a,b,c,d] --- Dequeue(F) F: [b,c,d] a Dequeue(F) F: [c,d] b Enqueue(F,e) F: [c,d,e] --- Enqueue(F,f) F: [c,d,e,f] --- Enqueue(F, Dequeue(F)) F: [d,e,f] c F: [d,e,f,c] --- Dequeue(F) F: [e,f,c] d Dequeue(F) F: [f,c] e Dequeue(F) F: [c] f
Notao Linear de uma Fila: F: [a1, a2..., an-1, an] Notao grfica: 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:
Comeo
a1 a2 ... an-1 an
Final
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 42
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
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 43
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.
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 44
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);
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 45
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;
-
CENTRO EDUCACIONAL FUCAPI CURSO TCNICO INFORMTICA
APOSTILA ESTRUTURA DE DADOS
ESTRUTURA DE DADOS PGINA 46
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