Anda di halaman 1dari 34

Estrutura de dados para armazenamento Abstrao de Dados Um processo qualquer seqncia finita e ordenada de passos que visa promover

r 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. Quando a matria-prima usada num processo abstrata, isto , apresenta-se sob a forma de valores, quantidades ou smbolos, ento falamos em processamento de dados. Quando o processamento realizado por um computador, entrada refere-se aos dados que so colhidos do mundo real, externo ao computador, e processo refere-se a uma srie finita de operaes que so realizadas a partir destes dados, a fim de transform-los em alguma informao desejada (sada). Claramente, os dados a serem processados pelo computador representam uma abstrao de parte da realidade; ou seja, representam algumas caractersticas selecionadas das entidades do mundo real, necessrias para a soluo de um determinado problema. Sempre que resolvemos problemas utilizando computador, a abstrao de dados se faz necessria, j que no podemos trabalhar dentro do computador diretamente com os objetivos envolvidos no problema. Devido grande importncia da abstrao para o processamento de dados em computador, enquanto programadores, a nossa ateno dever estar voltada a duas questes bsicas: Como representar a abstrao da realidade dentro do computador? Como representar o conhecimento necessrio para manipular esta

abstrao? Tipos de Dados A unidade bsica de informao dentro da memria do computador o bit (binary digit); os dgitos 0 e 1 so usados para representar os dois possveis estados de bit particular. Obviamente, com um nico bit no podemos representar muita informao. Entretanto, a memria do computador constituda de uma quantidade

muito grande de bits que, uma vez agrupados, so capazes de representar uma enorme quantidade e variedade de informaes. A forma segundo a qual os bits so agrupados, interpretados e manipulados pelo computador normalmente no nos interessa quando a nossa preocupao maior resolver um problema especifico. Por exemplo, se tivermos que codificar um programa para calcular e imprimir a mdia final de um aluno, num curso onde foram aplicadas duas provas, tudo o que precisamos de uma linguagem de programao atravs da qual possamos representar e operar os dois valores. No nos interessa saber exatamente como o computador far insto internamente. Tipos de Dados Abstratos Um tipo de dados abstrato formado por um conjunto de valores e por uma serie de funes que podem ser aplicadas sobre estes valores. Funes e valores, em conjunto, constituem um modelo matemtico que pode ser empregado para modelar e solucionar problemas do mundo real; servindo para especificar as caractersticas relevantes dos objetos envolvidos no problema, de que forma eles se relacionam e como podem ser manipulados. Entretanto, sendo o tipo de dados abstrato apenas um modelo matemtico, sua definio no leva em considerao como os valores sero representados na memria do computador (organizao dos bits), nem se preocupa com o tempo que ser gasto para aplicar as funes (rotinas) sobre tais valores. Para que possamos realmente aplicar um modelo matemtico na resoluo de problemas por computador, preciso antes transform-lo num tipo de dados concreto (ou simplesmente, tipo de dados). A transformao de um tipo de dados abstrato em um tipo de dados concreto chamada implementao. durante o processo de implementao que a estrutura de armazenamento dos valores especificada, e que os algoritmos que desempenharo o papel das funes so projetados. Objetivos das Estruturas de Dados O estudo das estruturas de dados envolve dois objetivos complementares: Terico: identificar e desenvolver modelos matemticos, determinando que classes de problemas possam ser resolvidos com o uso deles;

Pratico: criar representaes concretas dos objetivos e desenvolver rotinas

capazes de atuar sobre estas representaes, de acordo com o modelo considerado.

O primeiro objetivo considera um tipo de dados abstrato como um recurso a ser empregado durante a resoluo de problemas em geral; e o segundo considera a implementao deste tipo de dados abstrato como um problema em si, que pode ser resolvido atravs do uso de outros tipos de dados j disponveis, possivelmente predefinidos na linguagem escolhida para a implementao. Muitos modelos matemticos (estruturas de dados) j foram identificados como adequados para resolver vrias classes de problemas. Alguns destes modelos so notavelmente importantes no desenvolvimento de software. Assim, neste trabalho nos ocuparemos mais do segundo objetivo, isto , veremos como implementar as principais estruturas de dados em computador. Para ilustrar como a escolha da estrutura de dados correta pode levar a programas elegantes e eficientes, algumas aplicaes praticas sero desenvolvidas. PILHAS A pilha uma das estruturas de dados mais teis em computao. Uma infinidade de problemas clssicos da rea podem ser resolvidos com o uso delas.

Fundamentos: Uma pilha um tipo especial de lista linear em que todas as operaes de insero, remoo ou consulta so realizadas em uma s extremidade, denominada TOPO. Cada vez que um novo elemento deve ser inserido na pilha, ele colocado no seu topo; e em qualquer momento, apenas aquele posicionado no topo da pilha pode ser removido. Percebemos claramente um padro de comportamento que indica que o ltimo elemento a ser inserido (empilhado), o primeiro elemento a ser removido.

Esse o motivo das pilhas serem tambm referenciadas como uma estrutura LIFO (Last In, First Out). Por definio, uma lista LIFO uma estrutura dinmica, ou seja, uma coleo que pode aumentar e diminuir durante a sua existncia. Alis, o nome pilha, usado como sinnimo para lista LIFO, advm justamente da semelhana entre o modo como as listas LIFO crescem/diminuem e o modo como as pilhas no mundo real, funcionam, O exemplo mais comum do quotidiano e uma pilha de pratos, porque ela aumenta e diminui somente por um nico lado: o seu topo. Nessa analogia, percebemos que o topo o que se movimenta, e no a base. Por definio, uma lista LIFO uma estrutura dinmica, ou seja, uma coleo que pode aumentar e diminuir durante a sua existncia. Alis, o nome pilha, usado como sinnimo para lista LIFO, Advm justamente da semelhana entre o modo como as listas LIFO crescem/diminuem e o modo como as pilhas, no mundo real, funcionam. Uma pilha suporta trs operaes bsicas, tradicionalmente denominadas como: - Top: - Pop: acessa o elemento posicionado no topo da pilha; remove um elemento do topo da pilha.

- Push: insere um novo elemento no topo da pilha;

Entra-------

------------Sai

_____________ (_____________) ----------topo (_____________) (_____________) __(_____________)___ Uma pilha de pratos 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 a pilha diminua, removendo e retornando o elemento existente 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 remov-lo. Observe a seguir, como estas operaes interagem para alterar o estado de uma pilha P, inicialmente vazia, cuja extremidade esquerda foi escolhida como topo:

Operao

Estado da Pilha

Resultado

---------------Push (P,a) Push (P,b) Push (P,c) Pop (P) Pop (P) Push (P,d) Push (P,e) Top (P) Pop (P) Pop (P)

P: [

--------------------------------------------------------------------c b ----------------------------------e e d

P: [ a ] P: [ b, a ] P: [ c, b, a ] P: [ b, a ] P: [ a ] P: [ d, a ] P: [ e, d, a ] P: [ e, d, a ] P: [ d, a ] P: [ a ]

Sucessivos estados de uma pilha na notao linear Analisando os estados sucessivos que a pilha P assume, podemos entender por que a operao de insero denominada Push (empurre). Cada vez que um novo elemento colocado no topo da pilha, como se ele empurrasse para Baixo os demais elementos existentes. Algumas vezes, usado tambm o termo push-down (empurre para baixo) para designar esta operao. Analogamente, quando um elemento removido, como se os demais o pressionassem por baixo at que ele saltasse, pop-up significa justamente isto: saltar para cima. Um exemplo bastante ilustrativo, que nos permite entender a origem dos termos push-down e pop-up um porta guardanapos de papel, daqueles normalmente encontrados em lanchonetes.

Trata-se de um dispositivo equipado com uma mola que exerce certa presso por baixo dos guardanapos e que s permite o acesso quele existente no topo. Quando um novo guardanapo deve ser inserido devemos pression-lo no topo do dispositivo, de modo a empurrar para baixo os demais guardanapos existentes. Quando um guardanapo retirado, a presso exercida pela mola empurra os guardanapos para cima, fazendo com que um novo guardanapo aparea no topo. Devemos considerar esta analogia com cuidado, a existncia da mola que facilita a retirada ou a colocao de um papel, isto pode causar a impresso de que a base da pilha que se movimenta, quando, na realidade, o topo que faz a movimentao.

Init, IsEmpty e IsFull Imagine uma pilha de pratos sobre uma mesa, dentro de uma sala. Seria possvel colocar novos pratos indefinidamente sobre ela? Obviamente, no! Em algum momento o prato do topo da pilha tocaria o teto da sala. E o contrrio: seria possvel remover pratos do topo da pilha indefinidamente? Tambm no! Em algum momento a pilha tornar-se-ia vazia. A mesa e o teto so limites fsicos que impedem que a pilha cresa ou diminua indefinidamente. Da mesma forma, ao implementarmos uma pilha dentro do computador, a quantidade de memria alocada para representar seus elementos funciona como fator limitante. Voltando a pilha de pratos, antes de comearmos a empilhar sobre a mesa, devemos garantir que a mesma esteja limpa, isto , que no exista nenhum objeto no local onde sero colocados os pratos. Para adicionar um prato pilha, primeiro verificamos se ainda existe espao entre o topo da pilha e o teto da sala. Finalmente, para remover, precisamos nos certificar de que ainda existem pratos sobre a mesa. Assim, precisamos de mais trs operaes essenciais para manipular pilhas:

- Init - IsFull

: inicializa a pilha no estado vazia; : verifica se a pilha est cheia.

- IsEmpty : verifica se a pilha est vazia;

Sempre que a varivel criada, ela permanece com contedo indefinido, at que um determinado valor seja a ela atribudo. Geralmente, a criao de uma varivel se restringe apenas alocao da rea de memria necessria para represent-la; nenhum valor inicial armazenado nesta rea, at que uma instruo especifica para esta finalidade seja executada. No caso de uma varivel do tipo pilha, isto no diferente. A operao Init (P) tem como objetivo definir um estado inicial para a pilha P. Por uma questo de bom senso, uma pilha sempre inicializada no estado vazia. Toda vez que criamos uma varivel pilha, antes de qualquer coisa, devemos inicializ-la para garantir que no haver nenhuma sujeira no local onde ela ser montada! Para verificar se uma pilha P est vazia, podemos usar a funo lgica IsEmpty (P), que toma como argumento a pilha em que estamos interessados e retorna verdadeiro somente se ela estiver vazia, sem nenhum elemento armazenado. A funo IsFull (P) usada para verificar se uma pilha est cheia, isto , ela retorna verdadeiro somente quando no h mais espao para armazenar nenhum elemento na pilha. Note que IsFull (P) no o inverso de IsEmpty (P). Quando IsEmpty (P) retorna falso, indicando que a pilha P no est vazia, no significa que ela se encontra cheia. Da mesma forma, quando IsFull (P) retorna falso, informando que a pilha P no est cheia, no quer dizer que ela esteja vazia. Uma pilha pode estar vazia, nem cheia. FILAS Quem nunca ouviu falar de fila? Impossvel, no ? As filas esto em toda parte, at na computao!

Fundamentos Uma fila uma lista linear na qual todas as inseres so realizadas em uma das extremidades (fim da fila). E, alm disso, todas as remoes e os acessos so realizados em outra extremidade (incio da fila). Esse o motivo pelo qual as filas so denominadas listas FIFO (First-In First-Out). (figura abaixo)

________________________ Remoes Inicio Uma estrutura da fila. Cada vez que uma operao de insero executada, um novo elemento colocado no final da fila. Na remoo, sempre retornado o elemento que aguarda h mais tempo na fila, ou seja, aquele posicionado no comeo. A ordem de sada corresponde diretamente ordem de entrada dos elementos na fila, de modo que os primeiros elementos que entram so os primeiros a sair. Um exemplo bastante comum de filas verifica-se num balco de atendimento onde pessoas formam uma fila para aguardar at serem atendidas. Naturalmente, devemos desconsiderar os casos de pessoas que furam a fila ou que desistem de aguardar! Diferentemente das filas no mundo real, o tipo de dados abstrato no suporta insero nem remoo no meio da lista. Inseres ________________________ Fim

comeo Uma fila de caixa bancrio.

final

A palavra queue, da lngua inglesa, significa fila. Por tradio, as duas operaes bsicas que uma fila suporta so denominadas como a seguir: - 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 o elemento x no seu final. A operao Dequeue(F,x) faz a fila diminuir, j que remove e retorna o elemento posicionado no seu comeo.

Operao

Estado da Fila

Resultado

----------------------Enqueue(F,a) Enqueue(F,b) Enqueue(F,c) Enqueue(F,d) Dequeue(F) Dequeue(F) Enqueue(F,e) Enqueue(F,f)

F:[ ] F:[ a ] F:[ a, b ] F:[ a, b, c ] F:[ a, b, c, d ] F:[ b, c, d ] F:[ c, d ] F:[ c, d, e ] F:[ c, d, e, f ] F:[ d, e, f, c ]

-----------------------------------------------------------------------------------------------A B --------------------------------------C -------------------D E F

Enqueue(F,Dequeue(F)) F:[ d, e, f ] Dequeue(F) Dequeue(F) Dequeue(F) F:[ e, f, c ] F:[ f, c ] F:[ c ]

Sucessivos estados de uma fila em notao linear

Fila dupla

uma lista linear na qual todas as inseres, as remoes e os acessos so realizados nos extremos direito ou esquerdo da lista linear. Fila dupla com sada ou entrada restrita Dependendo da prioridade necessria para um determinado elemento, a fila dupla pode ser classificada como fila de sada ou de entrada restrita. Uma fila dupla com sada restrita ocorre quando queremos dar prioridade a um determinado elemento, e, para isso, permitimos que, no momento da insero, o elemento seja colocado no inicio da fila dupla. No caso de uma pilha, se ocorrer um estouro de sua capacidade (overflow), no momento da insero de um novo elemento, podemos permitir que nesta situao o elemento da base seja removido (j que ele o elemento que est a mais tempo na pilha). Essa possibilidade de quebrarmos a regra bsica de uma pilha, que diz que a insero ou remoo s pode ocorrer pelo topo da pilha, d origem a uma estrutura denominada fila dupla com entrada restrita. Aplicaes de filas Apesar do conceito simples da fila, ele tem se mostrado essencial para o desenvolvimento de muitas aplicaes, sobretudo, quando se trata de simular no computador situaes reais, onde algum tipo de atendimento modelado. Colorindo regies grficas Uma interessante aplicao de fila em computao grfica so os algoritmos para colorir regies de desenhos, representados sob a forma de matrizes de pontos. A fila usada essencialmente como um local onde os pontos aguardam at serem coloridos; atravs dela que mantemos o registro dos pontos que ainda temos a colorir. Quando ela torna-se vazia, ento foram coloridos todos os pontos que

pertenciam mesma regio que o ponto inicial fornecido. Na prtica cada ponto da imagem a ser colorida seria um pixel ponto luminoso) num monitor de vdeo.

LISTAS LINEARES Uma das formas mais comumente usadas para se manter dados agrupados a lista. Afinal, quem nunca organizou uma lista de compras antes de ir ao mercado, ou ento uma lista dos amigos que iro acampar no feriado prolongado? As listas tem se mostrado um recurso bastante til e eficiente no dia-a-dia das pessoas. Em computao, no tem sido diferente: a lista so processos no estado pronto, de um certo sistema operacional esperando pelo uso do processador ou, ainda, a lista de servios de impressos aguardando pela liberao de uma impressora fsica. Fundamentos a propriedade seqencial de uma lista linear, que a base para sua definio e para o seu uso. Observamos que em uma lista linear existe um inicio, onde est o primeiro elemento; e um final, onde encontramos o ultimo elemento. A disciplina de acesso, ou seja, a forma pela qual se realizam as operaes de insero e de remoo de elementos nas listas o que determina algumas classificaes das listas lineares. Entre as diversas operaes que podemos realizar sobre listas, temos: - acessar um elemento qualquer da lista; - inserir um elemento numa posio especfica da lista; - remover um elemento de uma posio especfica da lista; - 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...... Considerando-se somente as operaes de acesso, insero e remoo, restritas aos extremos da lista, temos casos especiais que aparecem muito frequentemente na modelagem de problemas a serem resolvidos por computador. Tais casos especiais recebem tambm nomes especiais: - Pilha: lista linear onde todas as inseres remoes e acessos so realizados em um nico extremo. Listas com esta caractersticas so tambm denominadas listas LIFO (Last-In/Fist-Out, ou em portugus: ltimo que entra/primeiro de sai). -Fila: lista linear onde todas as inseres so feitas num certo extremo e todas as emoes e acessos so realizados no outro. Filas so tambm denominadas listas FIFO (First-In/First-Out, ou em portugus: primeiro que entra/primeiro de sai). -Fila Dupla: lista linear onde as inseres, remoes ou acessos so realizados em qualquer extremo. Filas Duplas so tambm denominadas DEQUE (Double-Ended Queue, ou em portugus: fila de extremidade Dupla). Uma Fila Dupla pode ainda gerar dois casos especiais: Fila Dupla de Entrada Restrita (se a insero for restrita a um nico extremo) e Fila Dupla de Sada Restrita (se a remoo for restrita a um nico e extremo).

Consideraes sobre a implementao de listas lineares De uma forma geral, em uma mesma implementao, ou seja, no mesmo programa, no utilizado o conjunto completo das operaes possveis sobre uma lista linear. Um motivo para que isso seja quase uma regra a dificuldade de manter uma boa eficincia para todas as operaes simultaneamente. Por exemplo, se uma implementao tem uma boa performance na insero ou na excluso de um elemento, pode ser pouco provvel que essa mesma implementao consiga tambm obter um bom desempenho na operao de busca de qualquer elemento da lista. Consideraes sobre a alocao de memria Ao desenvolver uma implementao para listas lineares, o primeiro problema que surge : como podemos armazenar os elementos da lista, dentro do computador? Sabemos que antes de executar um programa, o computador precisa carregar seu cdigo executvel para a memria. Neste momento, uma parte da memria total

disponvel no sistema e reservada para uso do programa e o restante fica livre, pois raramente um programa ir ocupar toda a memria instalada no computador. Da rea de memria que reservada ao programa, uma parte usada para armazenar as instrues a serem executadas e a outra destinada ao armazenamento dos dados. Quem determina quanto de memria ser usado para as instrues o compilador. Alocar rea para armazenamento de dados, entretanto responsabilidade do programador.

Alocao Esttica versus Dinmica Dizemos que as variveis de um programa tem alocao esttica se a quantidade total de memria utilizada pelos dados previamente conhecida e definida de modo imutvel, no prprio cdigo-fonte do programa. Durante toda a execuo, a quantidade de memria utilizada pelo programa no varia. Por outro lado se o programa capaz de criar novas variveis enquanto executa, isto , se reas de memria que no foram declaradas no programa passam a existir durante a sua execuo, ento dizemos que a alocao dinmica. Considerando que uma varivel nada mais que uma rea de memria, dizemos que sua alocao esttica se sua existncia j era prevista no cdigo do programa; de outra forma, dizemos que sua alocao dinmica.

Alocao seqencial

A forma mais natural de armazenar uma lista dentro do computador consiste em colocar os seus elementos em clulas de memria consecutivas, um aps o outro.

Alocao encadeada Ao invs de manter os elementos agrupados numa rea continua de memria, isto , ocupando clulas consecutivas, na alocao encadeada os elementos podem ocupar quaisquer clulas (no necessariamente consecutivas) e, para manter a relao de ordem linear, juntamente com cada elemento armazenado o endereo do prximo elemento da lista. Desta forma, na alocao encadeada, os elementos so armazenados em blocos de memria denominados nodos, sendo que cada nodo composto por dois campos: um para armazenar dados e outro para armazenar endereo. rvores Binrias Definies Bsicas rvores so estruturas de dados extremamente teis em muitas aplicaes. Uma rvore formada por um conjunto finito T de elementos denominados vrtices ou ns de tal modo que se T = 0 a rvore vazia, caso contrrio temos um n especial chamado raiz da rvore (r), e cujos elementos restantes so particionados em m>=1 conjuntos distintos no vazios, as subrvores de r, sendo cada um destes conjuntos por sua vez uma rvore.

A forma convencional de representar uma rvore est indicado na figura abaixo. Esta rvore tem nove ns sendo A o n raiz.

Uma Os na Figura abaixo no uma rvore.

rvore conjuntos das

subrvores tem de ser disjuntos tem de ser disjuntos portanto a estrutura indicada

Estrutura que no representa uma rvore rvores Binrias A figura abaixo mostra um importante tipo de rvore que a rvore binria. Em uma rvore binria cada n tem no mximo duas subrvores, e quando h somente uma presente necessrio distinguir entre subrvore esquerda e direita. rvores binrias podem ser vistas em diversas situaes do cotidiano. Por exemplo, um torneio de

futebol eliminatrio, do tipo das copas dos pases, como a Copa do Brasil, em que a cada etapa os times so agrupados dois a dois e sempre so eliminados metade dos times uma rvore binria.

Formalmente uma rvore binria pode ser definida como um conjunto finito de ns, que vazio, ou consiste de um n raiz e dois conjuntos disjuntos de ns, a subrvore esquerda e a subrvore direita. importante observar que uma rvore binria no um caso especial de rvore e sim um conceito completamente diferente. Uma rvore estritamente binria uma rvore binria em que cada n tem 0 ou 2 filhos. Uma rvore binria cheia uma rvore em que se um n tem alguma subrvore vazia ento ele est no ltimo nvel. Uma rvore completa aquela em se n um n com algumas de subrvores vazias, ento n se localiza no penltimo ou no ltimo nvel. Portanto, toda rvore cheia completa e estritamente binria. A Figura mostra uma rvore estritamente binria, completa e cheia.

Armazenamento de rvores Binrias Para armazenar cada n de uma rvore binria precisamos de uma estrutura que contenha dois ponteiros: um aponta para a subrvore esquerda e outro para a subrvore direita. Naturalmente, devemos ter o(s) campo(s) para armazenar as informaes que o n deve conter. Uma Aplicao de rvores Binrias As rvore binrias so estruturas importantes toda vez que uma deciso binria deve ser tomada em algum ponto de um algoritmo. Vamos agora, antes de passar a algoritmos mais complexos, mostrar uma aplicao simples de rvores binrias. Suponhamos que precisamos descobrir nmeros duplicados em uma lista no ordenada de nmeros. Uma maneira comparar cada novo nmero com todos os nmeros j lidos. Isto aumenta em muito a complexidade do algoritmo. Outra possibilidade manter uma lista ordenada dos nmeros e a cada nmero lido fazer

uma busca na lista. Outra soluo usar uma rvore binria para manter os nmeros. O primeiro nmero lido colocado na raiz da rvore. Cada novo nmero lido comparado com o elemento raiz, caso seja igual uma duplicata e voltamos a ler outro nmero. Se for menor repetimos o processo com a rvore da direita e se maior com a rvore da esquerda. Este processo continua at que uma duplicata encontrada ou uma rvore vazia achada. Neste caso, o nmero inserido na posio devida na rvore. Considere que os nmeros 7 8 2 5 8 3 5 10 4 foram fornecidos pelo usurio, neste caso a rvore binria mostrada nesta Figura.

Percorrendo rvores Binrias Uma operao muito comum percorrer uma rvore binria, o que significa passar por todos os ns, pelo menos uma vez. O conceito de visitar significa executar uma operao com a informao armazenada no n, por exemplo, imprimir seu contedo. Na operao de percorrer a rvore pode-se passar por alguns ns mais de uma vez, sem porm visit-los. Uma rvore uma estrutura no seqencial, diferentemente de uma lista, por exemplo. No existe ordem natural para percorrer rvores e portanto podemos escolher diferentes maneiras de percorr-las. Ns iremos estudar trs mtodos para percorrer rvores. Todos estes trs mtodos podem ser definidos recursivamente e se baseiam em trs operaes bsicas: visitar a raiz, percorrer a subrvore da

esquerda e percorrer a subrvore da direita. A nica diferena entre estes mtodos a ordem em que estas operaes so executadas. O primeiro mtodo, conhecido como percurso em pr-ordem, implica em executar recursivamente os trs passos na seguinte ordem. 1. 2. 3. Visitar a raiz; Percorrer a subrvore da esquerda em pr-ordem; Percorre a subrvore da direita em pr-ordem.

Algoritmo de Huffman Para analisarmos mais uma aplicao de rvores binrias vamos considerar o problema de codificar uma mensagem composta de uma seqncia de smbolos de um alfabeto de n smbolos. Esta mensagem ser transformada em uma seqncia de bits, depois de a cada smbolo for atribudo um cdigo binrio e os cdigos dos smbolos da mensagem forem concatenados. Considere um alfabeto composto de quatro smbolos A, B, C e D, sendo que a cada um dos smbolos foi atribudo o cdigo indicado a seguir: Smbolo A B C D Cdigo 00 01 10 11

A mensagem ABCADCA seria codificada da seguinte maneira 00011000111000, tendo comprimento de 14 bits. O objetivo do algoritmo criar um cdigo que minimize o comprimento da mensagem. Para criar este cdigo vamos levar em conta a freqncia de cada smbolo na mensagem. A Tabela a seguir mostra a freqncia de cada smbolo na mensagem: Smbolo A B C Freqncia 3 1 2

D 1 Desta tabela podemos verificar que se atribuirmos ao smbolo A um cdigo binrio mais curto que os atribudos aos smbolos B e D teramos uma mensagem menor. Isto provm do fato que o smbolo A aparece mais vezes do que os smbolos B e D. Suponha que os seguintes cdigos sejam atribudos aos smbolos:

Smbolo A B C

Cdigo 0 110 10

D 111 Usando este cdigo a mensagem ABCADCA ficaria 0110100111100 que requer 13 bits. Em mensagens longas com mais smbolos infreqentes o ganho pode ser maior. Um dos requerimentos deste cdigo que nenhum cdigo seja prefixo de outro, caso a decodificao seja feita da esquerda para direita. Para decodificar a mensagem vamos comear da esquerda para a direita, caso o primeiro bit seja 0 o cdigo corresponde ao smbolo A. No caso contrrio devemos continuar a examinar os bits restantes. Se o segundo bit for 0 o smbolo um C, caso contrrio examinamos o terceiro bit, um 0 indica um B e D no outro caso. Do que vamos at agora o algoritmo para encontrar o algoritmo timo o seguinte. Encontre os dois smbolos que aparecem com menor freqncia, no nosso caso B e D. Atribumos 0 para B e 1 para D. Combine estes dois smbolos em um BD. Este novo smbolo ter freqncia igual a soma das freqncias de B e D, no caso 2. Temos agora os seguintes smbolos A (3), C (2) e BD (2), os nmeros entre parnteses so as freqncias. Novamente devemos escolher os smbolos de menor freqncia, que so C e BD. Atribumos o cdigo 0 ao smbolo C e 1 ao BD. Isto significa adicionar 1 aos cdigos de B e D, que passam a valer 10 e 11 respectivamente. Os dois smbolos so combinados ento no smbolo CBD de freqncia 4. Temos agora dois smbolos A (3) e CBD (4). Atribumos 0 ao smbolo A e 1 ao smbolo CBD. O smbolo ACBD o nico smbolo restante e recebe o cdigo NULL de comprimento 0. A Figura abaixo mostra a rvore binria que pode ser construda a partir deste exemplo. Cada n representa um smbolo e sua freqncia.

rvore de Huffman Removendo Ns de rvores Binrias Para remover um n de uma rvore binria devemos considerar trs casos: 1. 2. 3. n sem filhos; n com um nico filho; n com dois filhos.

O caso de um n sem filhos o mais simples e significa apenas ajustar o ponteiro de seu pai. A Figura remov0 ilustra este caso, onde o n com o valor 8 removido. No caso do n ter um nico filho a mudana na rvore tambm simples significa mover o n filho daquele ser removido uma posio para cima como est ilustrado na Figura remove1, onde o n com o valor 6 removido. O caso mais complexo o do n com dois filhos. Neste caso devemos procurar o sucessor s (ou antecessor) do n dever ocupar este lugar. Este n (sucessor) um descendente que est na subrvore da direita do n e corresponde ao n mais esquerda desta rvore. Ele no tem filhos esquerda e a sua rvore direita pode ser movida para o lugar de s. A Figura remove2 ilustra o caso de remoo do n com o valor 12. Observe que o n 13 (sucessor) assumiu o lugar do n 12.

Removendo n (8) sem filhos.

Removendo n (6) com um filho.

Removendo n (12) com dois filhos.

rvores Binrias Balanceadas Uma rvore binria balanceada, chamada de rvore AVL, uma rvore binria na qual as alturas das duas subrvores de cada um dos ns nunca diferem em mais de 1. O balanceamento de um n igual a diferena entre as suas altura esquerda e direita. Portanto, cada n de uma rvore balanceada tem balanceamento igual a -1, 0 ou 1, dependendo da comparao entre as alturas esquerda e direita. Lembrando que a altura de um n n da rvore o nmero de ns do maior caminho de n at um de seus descendentes. As folhas tem altura 1. Uma rvore binria completa com n>0 ns tem altura mnima, que igual a 1 + floor(log (n)). A Figura abaixo mostra uma rvore binria balanceada. Os valores dentro do n so altura do n e seu balanceamento.

rvore binria balanceada. Caso a probabilidade de pesquisar uma chave em uma tabela seja a mesma para todas as chaves, uma rvore binria balanceada ter a busca mais eficiente. Infelizmente o mtodo de insero em rvores binrias apresentado anteriormente no garante que a rvore permanecer balanceada. Como j vimos a estrutura da rvore depende da ordem em que as chaves so inseridas na rvore. A Figura mostra possibilidades de insero na rvore e o que ocorreria com o seu balanceamento. Cada insero que mantm a rvore balanceada est indicada por um B e as que desbalanceiam a rvore por um D. Observe que uma rvore se torna desbalanceada quando o n inserido se torna descendente esquerdo de um n que tinha anteriormente um balanceamento de 1 ou se ele se tornar descendente direito de um n que tinha anteriormente balanceamento de -1. Isto fcil de deduzir, por exemplo, um n que tinha balanceamento 1 e recebe um descendente direito aumenta sua altura em 1, portanto aumentando o seu desbalanceamento.

rvore balanceada e suas possibilidades de insero Observemos uma subrvore que ser tornar desbalanceada quando ocorrer uma insero. Vamos supor tambm que este n tem um balanceamento de 1. Neste caso o desbalanceamento ocorrer se a insero ocorrer em um n da direita. A Figura mostra um exemplo deste caso.

Insero em rvore binria Observar que o n A tem balanceamento 1, isto significa que a subrvore da esquerda tem altura no nula e maior em uma unidade que a da direita. Ao inserirmos um n na subrvore da direita a sua altura aumenta de um e o balanceamento passa para 2. Observar tambm que como o n mais jovem a se tornar desbalanceado o A, o seu filho pela esquerda tem de ter balanceamento igual 1. 2. a 0. Para manter a rvore balanceada necessrio que a transformao na rvore de tal modo que: a rvore permanea uma rvore de busca binria; a rvore continue a ser uma rvore balanceada.

Para isto vamos definir a operao de rotao em uma rvore. Uma rotao pode ser direita ou esquerda. A Figura abaixo mostra uma rvore e os resultados dos dois tipos de rotao sobre esta rvore esto mostrados na Figura a seguir.

rvore original antes da rotao

Efeitos das rotaes Tcnicas de ordenao de dados Fundamentos No nosso dia-a-dia, comum vermos as vantagens de manipular um conjunto de dados previamente callassificado, como, como, por exemplo, procurar o telefone de

uma determinada pessoa em uma lista telefnica. Neste caso, percebemos que essa simples tarefa de consulta poderia ser extremamente exaustiva se a lista telefnica no estivesse classificada por ordem alfabtica dos nomes dos assinantes. Observamos que a ordenao dos dados pode facilitar e aumentar a eficincia das operaes de pesquisa sobre um conjunto de dados. A ordenao pode ser realizada de forma a colocar uma ordem crescente ou decrescente em um conjunto de dados. Se considerarmos um conjunto de entrada em uma seqncia qualquer de vrios nmeros, depois de efetuarmos uma classificao nessa entrada, a sada resultar em uma seqncia dos nmeros de entrada reordenada. A seqncia de entrada, normalmente, um vetor com vrios elementos. Mas existem outras possibilidades de estruturas de dados, como, por exemplo, uma lista ligada. De forma prtica, os elementos a serem ordenados so trabalhados como um conjunto de dados denominado registro, em vez de serem manipulados de forma isolada. Assim, o conjunto de registros forma uma tabela. Cada registro contm uma chave, que o valor a ser ordenado, e demais valores, que sempre acompanham a chave. Isso significa que quando realizamos um processo de ordenao, se houver a necessidade de trocar a posio de uma chave, ocorrer tambm a alterao da posio de todos os elementos do registro. Com o objetivo de minimizar a tarefa computacional de movimentao de dados durante um processo de ordenao, observa-se que, na prtica, quando os registros possuem uma grande quantidade de dados (alm da chave), o processo de ordenao pode ser realizado com o uso de um veto (ou lista) de ponteiros para os registros. Vamos apresentar trs possibilidades de realizar a ordenao sobre uma seqncia de entrada: contigidade fsica, valor indireto e encadeamento: - Contigidade fsica: Existe uma forte caracterstica fsica no processo de ordenao, porque os elementos de um registro so movimentados de sua posio fsica original para sua no posio. - Vetor indireto de ordenao: No h a movimentao das entradas das posies originais. Isso possvel porque a classificao realizada com o apoio de um arquivo ndice. justamente esse arquivo que contm apontadores para os registros reais, os quais so mantidos classificados.

- Encadeamento: Tambm no h a movimentao dos registros das posies originais. A ordem desejada conseguida pelo uso de uma lista ligada. Coloca-se um campo a mais na tabela para permitir que seja identificado sempre o prximo registro. Dessa forma, no mais necessrio o vetor adicional (vetor indireto de ordenao), mas temos de utilizar um ponteiro para o primeiro elemento da lista ligada formada para a classificao desejada. Ordenao interna versus ordenao externa A ordenao interna usada em um conjunto de dados pequeno, porque o processo de ordenao pode ser realizado inteiramente (ou quase) na memria principal. J a ordenao externa usada em um conjunto de dados grande, quando seria praticamente impossvel colocar esse conjunto de dados na memria principal. A conseqncia que a ordenao tem de contar com o auxilio de memria auxiliar de armazenamento de massa, tais como, fitas ou discos. Vamos abordar apenas alguns dos principais mtodos de ordenao interna: Ordenao por insero: Insero direta; Incrementos decrescentes (Shell sorte) Ordenao por troca: Mtodo de bolha (bubble sort) Mtodo de troca e partio (quicksort) Ordenao pro seleo: Seleo direta; Seleo em rvore (heapsort). Ordenao por insero Como o prprio nome sugere, a classificao obtida porque os elementos so inseridos na sua posio correta, levando-se em conta os elementos j classificados. Existem duas possibilidades: a insero direta e o mtodo Shell. Insero direta o mtodo mais simples, normalmente utilizado para um conjunto pequeno de dados. Isso acontece porque esse mtodo apresenta uma baixa eficincia em relao ao tempo total para realizar uma classificao. medida que o conjunto de dados a ser classificado aumenta, observa-se uma queda no tempo necessrio para termos o conjunto de dados classificado.

Existe a diviso do vetor a ser ordenado em dois segmentos: o primeiro segmento contendo os elementos j ordenados e o segundo segmento contendo os elementos ainda no ordenados. Algoritmo de insero direta Podemos definir um algoritmo da insero direta da seguinte maneira: a. b. Um primeiro elemento est no vetor ordenado e os demais no vetor desordenado; Retira-se o primeiro elemento do vetor desordenado. Ao coloc-lo no vetor ordenado, realizada a devida comparao para inseri-lo na sua posio correta; c. Repete-se o processo at que todos os elementos do vetor desordenado tenham passado para o vetor ordenado. Os trs passos anteriores podem ser usados para construir um algoritmo mais detalhado na notao do pseudocdigo. Incrementos decrescentes (Shell sort) Este algoritmo foi proposto por Ronald L.Shell (1959). considerado uma extenso do algoritmo de insero direta, pois a diferena reside apenas no numero de segmentos do vetor usado para o processo de classificao. Na insero direta, existe apenas um nico segmento do vetor onde os elementos so inseridos ordenadamente, enquanto no mtodo Shell so considerados diversos segmentos. Ordenao por troca No processo de ordenao por troca, a idia fazer uma varredura no vetor como um todo. No momento em que dois elementos fora de ordem forem encontrados, suas posies so simplesmente trocadas. Esse processo de varredura pressupe a realizao de comparaes sucessivas de pares de elementos. Mtodo da bolha (bubble sort) considerado um mtodo bastante trivial e, de forma geral, muito lento na realizao da ordenao de um conjunto de dados. O nome bolha deve-se ao fato de que, ao fazer o acompanhamento ilustrativo do processo da ordenao, tem-se a impresso de que os valores flutuam at sua correta posio, como bolhas em um lquido. Mtodo da troca e de partio (quick sort)

Foi proposto por C.A.Hoare em 1962, e considerado como o mais rpido em relao aos mtodos apresentados anteriormente, sendo este o principal motivo de sua preferncia quando necessrio classificar um conjunto de dados. Adota como principio que mais rpido classificar dois vetores com n/2 elementos cada um, do que um com n elementos; ou seja, segue a linha do dividir para conquistar (dividir um problema maior em dois menores para que haja o domnio da complexidade do problema original). Anlise comparativa So apresentados trs quadros comparativos do tempo gasto na ordenao de vetores com 500, 5000, 10000 e 30000 elementos. O primeiro quadro pressupe que o conjunto de dados de entrada que ser classificado esteja posicionado de forma aleatria (1, 55, 4, 88, 10, 3, .., n), o segundo quadro assume os dados j esto em ordem crescente (1, 2, 3, 4, ..., n) e, finalmente, o terceiro quadro assume que os dados j esto em ordem decrescente (n, n-1, n-2, .., 1) Nos trs quadros exibidos abaixo, os mtodos que apresentaram menor tempo para realizao da ordenao receberam um valor um (1). Os outros mtodos que apresentaram um tempo maior para realizao da ordenao receberam um valor comparativo ao mais rpido, por exemplo, 1, 6. 500 5000 10000 30000 Insero 11,3 87 161 Shell 1,2 1,6 1,7 Quick 1 1 1 Seleo 16,2 124 228 Heap 1,5 1,6 1,6 Ordem aleatria 0 2 1 0 1,6

500 5000 10000 Insero 1 1 Shell 3,9 6,8

30000 1 7,3

1 8,1

Quick Seleo Heap Ordem crescente

4,1 128 12,2

6,3 1524 20,8

6,8 3066 22,4

7,1 0 24,6

500 5000 10000 30000 Insero 40,3 305 575 Shell 1,5 1,5 1,6 Quick 1 1 1 Seleo 29,3 221 417 Heap 2,5 2,7 2,7 Ordem decrescente

0 1,6 1 0 2,9

Analisando os quadros anteriores, podemos apresentar algumas recomendaes sobre os mtodos de ordenao apresentados: a. b. c. Se o tamanho do conjunto de dados < = 50, recomenda-se o mtodo de Se o tamanho do conjunto de dados < = 5000, recomenda-se o mtodo Shell Se o tamanho do conjunto de dados > 5000, recomenda-se o mtodo quick

insero; sort. Notamos que at 1000 elementos, Shell mais vantajoso. sort. Entretanto, esse mtodo necessita de memria adicional por ser recursivo. Ento se recomenda evitar chamadas recursivas para pequenos intervalos. Pode-se colocar um teste antes da recursividade (se n < = 50, insero; se n< = 1000, Shell sort); d. O mtodo heap sort apresenta-se de 2 a 3 vezes mais lento do que quick sort. Seu tempo sempre n log n, no importando a ordem dos elementos. Esse mtodo deve ser usado quando as aplicaes no podem tolerar eventuais variaes no tempo esperado para ordenao. Referncias Bibliogrficas: FORBELLONE, Andr Luiz Villar; EBERSPACHER, Henri Frederico. LGICA DE PROGRAMAO: a construo de algoritmos e estruturas de dados. 3. ed. So Paulo: Makron Books (Pearson Education). 2005.

GUIMARES, ngelo de Moura; LAGES, Newton Alberto de Castilho. ALGORITMOS E ESTRUTURAS DE DADOS. 8. ed. Rio de Janeiro: Livros Tcnicos e Cientficos Editora S. A. . 1985. SCHILDT, Herbert. C COMPLETO E TOTAL. 3. ed. So Paulo: Makron Books (Pearson Education). 1996. TENENBAUM, AAron M; LANGSAM, Yedidyah; AUGENSTEIN, Moshe J; SOUZA, Teresa Cristina Flix de. Estruturas de dados usando C. So Paulo: Makron Books, 1995. TERADA, Routo. Desenvolvimento de algoritmos e estrutura de dados. So Paulo: Makron Books do Brasil, 1991.

Anda mungkin juga menyukai