apostila estrutura de dados.pdf

46
CENTRO EDUCACIONAL FUCAPI CURSO TÉCNICO – INFORMÁTICA APOSTILA – ESTRUTURA DE DADOS ESTRUTURA DE DADOS – PÁGINA 1 APOSTILA ESTRUTURA DE DADOS MANAUS 2013

Upload: milton-jose-ferreira

Post on 18-Nov-2015

23 views

Category:

Documents


0 download

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