Construção de uma Ferramenta Didática para Ensino de

Propaganda
FACULDADE FARIAS BRITO
CIÊNCIA DA COMPUTAÇÃO
RODSON COELHO DOS REIS
CONSTRUÇÃO DE UMA FERRAMENTA DIDÁTICA PARA
ENSINO DE COMPLEXIDADE ALGORÍTMICA
Fortaleza
2011
RODSON COELHO DOS REIS
CONSTRUÇÃO DE UMA FERRAMENTA DIDÁTICA PARA
ENSINO DE COMPLEXIDADE ALGORÍTMICA
Monografia apresentada para obtenção dos créditos da disciplina
Trabalho de Conclusão do Curso da Faculdade Farias Brito,
como parte das exigências para graduação no Curso de Ciência
da Computação.
Orientador: MSc. Murilo Eduardo Ybanez Nascimento.
Fortaleza
2011
CONSTRUÇÃO DE UMA FERRAMENTA DIDÁTICA PARA
ENSINO DE COMPLEXIDADE ALGORÍTMICA
Rodson Coelho dos Reis
NOTA:
Data: ____/____/_______
BANCA EXAMINADORA
______________________________
MSc. Murilo Eduardo Ybanez Nascimento
(Orientador)
______________________________
MSc. Daniel Matos Alves
(Examinador)
______________________________
MSc. Maikol Magalhães Rodrigues
(Examinador)
FINAL (0-10): ______
AGRADECIMENTOS
Ao Orientador Prof. Murilo pela paciência e dedicação no trabalho, o que permitiu
que o projeto fosse concluído com qualidade.
Aos Professores: Paulo Lemos, Cleiton, Fláudio, Othon, Sérgio, Maikol, Jarbas,
Sales, Façanha, Wagner, Mateus, Azevedo e Brayner pela formação adquirida durante o
curso.
Aos meus pais Maria Dalva e Rosendo Lopes (in memoriam) pela educação,
amor, apoio e ensinamentos que foram base para formação do caráter e para transpor
obstáculos da vida.
RESUMO
Computadores não possuem recursos ilimitados, por isso, é necessário escrever algoritmos
que utilizem esses recursos de forma sensata. A análise da complexidade de algoritmos
possibilita desvendar a evolução dos custos de execução de um algoritmo em função do
tamanho da entrada. Por se tratar de uma área que envolve conceitos matemáticos não triviais,
a utilização de ferramentas didáticas adequadas pode auxiliar o professor na passagem do
conhecimento e os alunos na fixação dos conceitos. Este trabalho busca o desenvolvimento de
um software que suporte a definição de algoritmos, conte a quantidade de execuções de um
certo conjunto de operações indicadas pelo usuário para diferentes tamanhos de entradas e
apresente as curvas que representam as funções de complexidade, contribuindo para o ensino
e a aprendizagem da análise de complexidade de algoritmos.
Palavras
chave:
complexidade,
algoritmo,
desenvolvimento,
software,
educacional.
SUMÁRIO
1.
INTRODUÇÃO................................................................................................................... 13
2.
INFORMÁTICA NA EDUCAÇÃO ...................................................................................... 15
2.1 Critérios para Avaliação de Software Educacional .......................................................... 17
3.
2.1.1
Critérios para Avaliação de Qualidade de Software ..................................................... 18
2.1.2
Critérios para Avaliação da Interface de Software ....................................................... 19
2.1.3
Critérios para Avaliação do Software quanto aos Resultados de Aprendizagem ............ 20
METODOLOGIA PARA ANÁLISE DE ALGORITMOS...................................................... 22
3.1 Pseudocódigo .............................................................................................................. 23
4.
3.2
Contagem de Operações Primitivas ............................................................................... 24
3.3
Análise Assintótica ...................................................................................................... 26
3.3.1
Notação O ................................................................................................................ 27
3.3.2
Notação Ω ................................................................................................................ 28
3.3.3
Notação Θ ................................................................................................................ 29
DESENVOLVIMENTO DA APLICAÇÃO........................................................................... 30
4.1
Requisitos do Sistema ...................................................................................................... 30
4.1.1 .................................................................................................................................... 31
Requisitos Funcionais........................................................................................................... 31
4.1.2
4.2
Requisitos não Funcionais ......................................................................................... 31
Arquitetura ..................................................................................................................... 32
4.2.1
Modelagem Arquitetural ............................................................................................ 33
4.3
Ambiente de Desenvolvimento......................................................................................... 38
4.4
Tecnologias Empregadas ................................................................................................. 38
4.4.1
Reflection ................................................................................................................. 38
4.4.2
Annotation................................................................................................................ 40
4.4.3
ClassLoader.............................................................................................................. 41
4.4.4
JSyntaxPane ............................................................................................................. 42
4.4.5
JFreeChart ................................................................................................................ 43
4.4.6 PDFHelp .................................................................................................................. 44
5.
UTILIZAÇÃO DA FERRAMENTA ..................................................................................... 45
5.1
Interface ......................................................................................................................... 45
5.2 Palavras Reservadas ........................................................................................................ 48
5.3
6.
7.
Exemplos........................................................................................................................ 50
5.3.1
Exemplo 1 ................................................................................................................ 50
5.3.2
Exemplo 2 ................................................................................................................ 52
AVALIAÇÃO DA FERRAMENTA NO CONTEXTO EDUCACIONAL ............................... 58
6.1
Questionário ................................................................................................................... 58
6.2
Resultados ...................................................................................................................... 59
CONCLUSÃO.................................................................................................................... 62
REFERERÊNCIAS BIBLIOGRÁFICAS...................................................................................... 64
ANEXO A – ALGORITMO COMPLEMENTAR ......................................................................... 67
LISTA DE FIGURAS
Figura 1 - Exemplo de Pseudocódigo do Algoritmo Bolha ............................................................243
Figura 2 - Notação O ..................................................................................................................276
Figura 3 - Notação Ω ................................................................................................................... 27
Figura 4 - Notação Θ ..................................................................................................................298
Fi gura 5 - Diagrama de ati vidade da lógi ca geral da apli cação........................................................321
Fi gura 7 - Diagrama de Sequência da Aplicação ............................................................................376
Fi gura 8 - Exemplo code-completion no Netbeans........................................................................398
Fi gura 9 - Exemplo de instância de classe e exe cução de método via Refle ction. ............................398
Fi gura 10 - Hierarquia do ClassLoader.
Fonte(http://www.de veloper.com/img/arti cles/2003/08/14/cl _hierarchy.gif) ...............................410
Fi gura 11 - JSyntaxPane ............................................................................................................... 41
Fi gura 12 – Ilustra çãoJ Linechart (JFree Cha rt)...............................................................................432
Fi gura 13 - Inte gração do PDFHelp no Netbeans ...........................................................................443
Fi gura 14 - Tela principal da aplicação.........................................................................................465
Fi gura 15 - Help da aplicação.......................................................................................................476
Fi gura 16 - Escri ta da e xpressão @TamanhoEntrada .....................................................................498
Fi gura 17 - Escri ta da e xpressão @contar...................................................................................... 49
Fi gura 18 - Ge ração das entradas Exemplo 1 ................................................................................. 49
Fi gura 19 - Contagem das operações Exemplo 1............................................................................ 50
Fi gura 20 - Gráfi co Exemplo 1....................................................................................................... 51
Fi gura 21 - Contagem das operações Exemplo 2...........................................................................532
Fi gura 22 - Ge ração das entradas Exemplo 2 ................................................................................532
Fi gura 23 - Gráfi co Exemplo 2......................................................................................................543
Fi gura 24 - Contagem das operações Exemplo 3...........................................................................554
Fi gura 25 - Ge ração das entradas Exemplo 3 ................................................................................565
Fi gura 26 - Gráfi co Exemplo 3......................................................................................................565
LISTA DE TABELAS
Tabela 1 - Tamanho do Problema x Tempo de Execução ................................................................ 26
Tabela 2 - Descrição das classes do sistema................................................................................... 35
Tabela 3 - Pe rguntas x Cri térios .................................................................................................... 59
Tabela 4 - Resultado da a valiação do software .............................................................................. 60
LISTA DE ABREVIATURAS E SIGLAS
API
Application Programming Interface
IDE
Integrated Development Environment
JRE
Java Runtime Environment
JVM
Java Virtual Machine
MBTI
Myers Briggs Type Indicator
MVC
Model View Controller
13
1. INTRODUÇÃO
Com a disseminação do computador e da Internet, a utilização de softwares como
instrumento de aprendizado vem ganhando cada vez mais espaço no meio educacional. Esses
softwares
se
utilizam
da
grande
capacidade
de
armazenamento,
conectividade
e
processamento disponível nos computadores atuais para apresentar informações de maneiras
inovadoras e proporcionar experiências que podem ser utilizadas para fixar e ampliar os
conhecimentos em sala de aula.
Os softwares educativos podem auxiliar no processo de aprendizagem de várias
formas, valendo-se de recursos como animações, jogos, simulações, dentre outros. No caso
dos cursos de computação, ferramentas profissionais também são comumente usadas no
ensino das disciplinas. Um exemplo é a utilização dos Ambientes de Desenvolvimento
Integrados (Integrated Development Environment - IDE) pelos alunos para a codificação e
execução de algoritmos, como parte das práticas de lógica de programação e desenvolvimento
de sistemas.
Uma disciplina que poderia se beneficiar mais do uso de ferramentas didáticas
como apoio ao ensino é a análise da complexidade de algoritmos. O estudo da complexidade
de algoritmos se propõe a investigar o comportamento do custo de execução, seja em termos
de processamento ou memória, à medida que os dados de entrada aumentam. Quando o
conjunto dos dados de entrada é pequeno, qualquer algoritmo pode ser usado para resolver um
problema, porém, à medida que o tamanho da entrada cresce a eficiência do algoritmo se
torna um fator relevante.
14
Por esta razão, um conhecimento sólido sobre análise de complexidade de
algoritmos é fundamental para a formação de um profissional de Ciência da Computação, por
se tratar de uma ferramenta que permite avaliar a eficiência da estratégia utilizada na
codificação dos algoritmos e, em última instância, determinar a aplicabilidade dos mesmos na
solução de problemas reais.
O presente trabalho tem como objetivo definir e implementar um software que
seja um facilitador para professores, como um instrumento adicional a ser utilizado em sala de
aula, e para alunos, como uma ferramenta para exercitar os conhecimentos adquiridos, no que
tange à análise da complexidade dos algoritmos. Por outro lado, um bom software
educacional deve exibir certas características importantes tais como: uma boa usabilidade;
interface clara e objetiva; recuperação e notificação de erros de utilização e disponibilidade de
um módulo de ajuda para o usuário.
O trabalho está dividido em sete capítulos. O primeiro capítulo faz uma breve
introdução sobre o trabalho.
No segundo capítulo, encontra-se alicerce teórico sobre softwares educacionais e
os critérios de avaliação de uma aplicação no meio educacional.
O terceiro capítulo apresenta uma metodologia para análise de algoritmo e
fundamentos teóricos para representação dos custos dos algoritmos através de notações.
O quarto capítulo descreve os fatores que guiaram o desenvolvimento da
aplicação, tais como: requisitos, arquitetura, ambiente de desenvolvimento e tecnologias
utilizadas.
No quinto capítulo será ilustrado o funcionamento da aplicação através de
exemplos de algoritmos e validação dos resultados obtidos com a metodologia para cálculo de
complexidade.
O sexto capítulo descreve um processo de avaliação da ferramenta através de um
questionário e os resultados de avaliação.
O último capítulo exibe as conclusões finais do projeto, bem como sugestões para
trabalhos futuros.
15
2. INFORMÁTICA NA EDUCAÇÃO
A informática educativa é uma área da informática que trata da utilização de
computadores como instrumento de aprendizado, maximizando a difusão do conhecimento e
facilitado a assimilação de um conteúdo (SANTOS; COSTA, 2005).
Porém, de acordo com Zambalde e Alves (2002 apud SANTOS et COSTA, 2005),
a inserção da informática no segmento educacional provoca mudanças tanto estruturais quanto
comportamentais. A mudança estrutural ocorre devido à necessidade de se obter todo o
equipamento necessário para informatizar um ambiente. A mudança comportamental refletese na maneira de ensinar, aprender e adaptar-se a uma forma complementar de ensino.
Lucena (on-line) relata que havia um grande receio por parte dos professores de
que o uso do computador, como ferramenta de ensino, viesse a substituí-los em sala de aula.
Mas, atualmente há uma consciência sobre o emprego do computador devido à sua crescente
popularidade,
permitindo
ser um item complementar em um processo
extenso
de
aprendizagem.
A utilização do computador como meio de transmissão da informação ao aluno
reflete-se na informatização dos processos de ensino vigentes, o que facilita a adoção do
computador sem romper a dinâmica do meio educacional (VALENTE, 1997).
Valente (on-line) relata que capacitar o professor para utilizar os recursos
oferecidos pela informática como instrumento de ensino e aprendizagem não significa
incrementar o seu conhecimento com técnicas ou conhecimento de informática. É importante
que o professor saiba como integrar o computador à sua disciplina para tirar o maior proveito
16
dessa tecnologia. É necessário que o educador conheça o processo de aprendizagem, como ele
acontece e como intervir de maneira efetiva na relação aluno-computador.
O autor expõe ainda que o professor de uma disciplina deve ter conhecimento
sobre os potenciais educacionais do computador e ser capaz de distribuir adequadamente
atividades tradicionais de ensino com atividades que exigem o uso do computador.
Em sala de aula, as atividades informatizadas tanto podem ter um intuito de dar
continuidade à transmissão da informação ao aluno quanto propiciar melhores condições para
construção do conhecimento através de ambientes de aprendizagem.
Segundo Papert (1994 apud SANTANCHÉ et TEIXEIRA, 1999), a utilização do
computador no meio educacional se classifica em duas metodologias: instrucionista e
construcionista.
De acordo com Borges (2002), “o instrucionismo é a base do sistema adotado na
maior parte das escolas atuais”. A metodologia instrucionista fundamenta-se no ato de ensinar
por meio da transmissão da informação ao aluno (VALENTE, 1997). Nesse contexto, o
computador é um potencializador dessa metodologia, devido a sua grande capacidade de
programar instruções a serem passadas aos alunos. No caso, o computador é programado para
ensinar o aluno, funcionando como um guia para um conteúdo. Além disso, sistemas podem
validar as respostas fornecidas pelo aluno, livrando o professor de correções de exercícios e
provas.
No paradigma instrucionista, o professor não precisa de uma formação profunda
em informática aplicada à educação. Basta o professor ser treinado para conhecer o
funcionamento do computador e do software para utilizar como recurso adicional no ensino
de uma disciplina (VALENTE, on-line). O presente trabalho inspira-se no conceito
instrucionista.
A metodologia construcionista baseia-se na construção do conhecimento através
do computador (PAPERT, 1986 apud VALENTE 1997). Nesse sentido, a construção do
conhecimento ocorre quando um aluno constrói um objeto de seu interesse, como por
exemplo, um programa de computador. O conhecimento é adquirido pela prática da
construção do objeto e pelo envolvimento afetivo do aluno ao construir algo de seu interesse.
Quando o aluno interage com o computador ele está manipulando conceitos que contribuem
17
para o seu desenvolvimento cognitivo, da mesma forma que ele adquire conhecimento ao
interagir com objetos do mundo real.
Nesse caso, o computador é programado para ser
ensinado (VALENTE, 1997).
No paradigma construcionista, o professor precisa conhecer aspectos técnicos
sobre a ferramenta computacional, como, por exemplo, a linguagem de programação e o
banco de dados, conhecer sobre o processo de aprendizagem e ter uma noção sobre aspectos
sociais e afetivos que influenciam a aprendizagem. Todo esse conhecimento não é adquirido
através de treinamento, mas sim através de um processo de formação (VALENTE, on-line).
Dada uma visão geral sobre a informática na educação, a próxima subseção
descreverá as características de um software no âmbito educacional.
2.1 Critérios para Avaliação de Software Educacional
Um software educacional é um programa de computador cujo propósito é atender
os objetivos educacionais previamente estabelecidos. Para atingir esse objetivo, é necessário
que esse software seja desenvolvido em conjunto com especialistas da informática e da
educação, deixando-o efetivo e de acordo com os propósitos pedagógicos (ZAMBALDE et
ALVES, 2002 apud SANTOS et COSTA, 2005).
Lucena (on-line) cita que geralmente os softwares educacionais são desenvolvidos
por equipes que não são interdisciplinares e que, na maioria das vezes, são compostas por
engenheiros de software. Tal situação pode comprometer o trabalho dos educadores por conta
do uso de um produto que não corresponde às suas expectativas pedagógicas.
A autora ainda expõe que a avaliação de um software educacional se baseia em
três critérios fundamentais: qualidade, interface e os resultados da aprendizagem. O primeiro
critério refere-se à qualidade do software influenciada pela normatização dos processos de
desenvolvimento. O segundo critério refere-se à capacidade de comunicação do software. O
terceiro critério foca nos resultados e consequências da aprendizagem do usuário.
18
2.1.1
Critérios para Avaliação de Qualidade de Software
A qualidade de software é a satisfação de requisitos funcionais e de desempenho
explicitamente
declarados,
normas
de
desenvolvimento
explicitamente
documentadas e características implícitas que são esperadas em todo o software
desenvolvido profissionalmente. (PRESSMAN, 2006, p. 349).
Os requisitos funcionais são aqueles que descrevem as funcionalidades do
sistema.
Os requisitos de desempenho se baseiam em fatores como: tempo de resposta,
precisão, capacidade, etc. As normas de desenvolvimento são os critérios que guiam o
desenvolvimento do software. As características implícitas são atributos esperados de um
software tais como manutenibilidade e confiabilidade. Todas essas necessidades são
indispensáveis para propiciar a qualidade de qualquer software, inclusive de programas
educacionais.
No contexto específico de softwares educacionais, Lucena (on-line) elaborou um
conjunto de perguntas que expressam critérios para avaliação de qualidade de software, a fim
de facilitar o trabalho do educador ou avaliador:
1. O software reage ao usuário de maneiras previsíveis?
2. O software é simples com relação ao aprendizado das funções essenciais?
3. O software é visualmente atrativo com relação à apresentação do conteúdo?
4. O software permite localizar instruções sobre uso (help) independentemente da
situação em que o usuário se encontra?
5. O software apresenta erros eventuais ou intermitentes?
6. O tempo entre intervenções do usuário é tolerável?
7. O software reage adequadamente a erros grosseiros de utilização?
8. O software prevê procedimentos de recuperação para situações de falhas?
Portanto,
acredita-se
que
essas
perguntas
simplificam
aspectos
teóricos
relacionados aos critérios de qualidade de software educacional, facilitando a avaliação de um
professor que não tenha disponibilidade, comprometimento ou acessibilidade à literatura
correspondente (LUCENA, on-line).
Depois de estabelecidas as questões de qualidade de software, a subseção a seguir
abordará critérios para avaliação da interface homem-máquina.
19
2.1.2
Critérios para Avaliação da Interface de Software
“O projeto de interface com o usuário cria um meio efetivo de comunicação entre
o ser humano e o computador.“ (PRESSMAN, 2006). O projeto identifica os objetos e as
ações de interface e depois cria um padrão de tela que será a base para um protótipo de
interface com o usuário. A elaboração da interface é importante, pois molda a percepção do
software por parte do usuário.
Durante o processo de construção da interface para comunicação homemcomputador, é necessário levar em conta os objetivos do software e os requisitos do cliente
(LUCENA, on-line). Por exemplo, modelar um software educacional para usuários do ensino
fundamental é diferente de modelar um software para acadêmicos.
A autora ainda cita que é preciso antes definir objetivos e os perfis físico,
psicológico e intelectual dos alunos, para depois definir os aspectos do software educativo. A
escala apresentada no tipo de indicador Myers Briggs (Myers Briggs Type Indicator – MBTI)
descreve fatores psicológicos que influenciam na interação do homem com a máquina
(SHNEIDERMAN, 1987 apud LUCENA, on-line):
1. Usuários extrovertidos apreciam variedade de ação e estímulos externos;
usuários
introvertidos
trabalham
bem
sozinhos
e
desenvolvem
cuidadosamente suas ideias;
2. Usuários perceptivos gostam de novas situações, porém demonstram
indecisão em suas ações; outros, entretanto, planejam cuidadosamente suas
ações, levados pelo julgamento e procuram finalizar suas tarefas;
3. Usuários sentimentais transferem sua afetividade para a máquina, procurando
resolver os problemas apresentados pelo programa, numa tentativa de
agradar e de receber recompensas;
4. Usuários racionais colocam as funções em ordem, não se importando com
um tratamento impessoal.
Em se tratando da construção de interfaces para usuários de ambos o sexos, há
algumas questões a considerar (LUCENA, on-line):
1.
Uma interface pode ser perfeita para um determinado grupo de
usuários e pode não servir para outro;
20
2.
Uma interface pode ser suficiente para uma classe de tarefas e não para
outras;
3.
Uma interface pode ser utilizada em determinado equipamento e
periféricos e não em outros.
A interface deve ajudar no processo de comunicação e cognição, permitindo que o
usuário obtenha melhores resultados em sua área e atinja objetivo eficientemente e
eficazmente. Nesse sentindo, a interface deve (STAHL, 1988 apud LUCENA, on-line):
1.
Reduzir a ansiedade e o medo natural de manipulação da máquina.
Muito influem, para tal, os sistemas de ajuda e de consulta amigáveis,
bem como uma linguagem acessível e telas atraentes;
2.
Demonstrar uma evolução eficiente e gradativa de mensagens e
graus de complexidade em sua arquitetura de apresentação. Este
fator contribui para a agilização do processo de interação;
3.
Garantir a esperada retroalimentação (feedback )
com estratégias
inteligentes e abertas a informações com assistência a decisões dos
usuários. Através de respostas e perguntas do usuário, possibilitar um
diagnóstico em relação aos pré-requisitos e rapidez do andamento do
programa.
Entendida a importância das interfaces para usuários comuns e usuários do meio
educacional, a seguinte subseção descreve fatores para compreender os resultados de
aprendizagem que o software propicia.
2.1.3
Critérios para Avaliação do Software quanto aos Resultados de Aprendizage m
É de se esperar que os resultados de aprendizagem na utilização do software
dependam de qual abordagem o software se encaixa: instrucionista ou construcionista. Na
abordagem instrucionista, os resultados podem ser previstos e a avaliação da aprendizagem
pode ser passada ao aluno em tempo real. Na abordagem construcionista, a capacidade de
cognição do aluno é trabalhada mais intensivamente, já que ele constrói objetos e faz
reflexões. Assim, os resultados de aprendizagem são imprevisíveis.
21
Entretanto, de acordo com pesquisas sobre a construção do conhecimento e
compreensão humana, existem alguns fatores que influenciam o desenvolvimento mental
(GAGNÉ, 1986 apud Lucena on-line):
a) memória;
b) capacidade de solucionar problemas.
Um software educativo deve dispor às informações visando distribuir as
proposições da tela, de tal sorte que não sobrecarregue a memória do aluno. Uma tela de
software eficiente deve limitar a quantidade de informações para não comprometer o
aprendizado do usuário.
Na medida em que o ser humano vivencia situações ou problemas, ele procura
adotar estratégias mais gerais, ou seja, do seu julgamento, em busca de soluções. Por isso,
softwares devem ser minuciosamente analisados quanto à condução da solução dos problemas
para não gerar respostas inadequadas e, consequentemente, não levar o usuário para uma
estratégia equivocada. Além disso, o software deve ser desenvolvido para corresponder ao
nível de leitura e compreensão do aluno, caso contrário o impedirá de adquirir a compreensão
desejada.
22
3. METODOLOGIA PARA ANÁLISE DE ALGORITMOS
A metodologia para análise de algoritmo implementada na ferramenta baseia-se
no cálculo do tempo de execução de um algoritmo. Para realizar medições é preciso executar
um algoritmo sobre diferentes entradas com tamanhos distintos. O resultado pode ser
visualizado em um gráfico, onde o eixo das abscissas corresponde às entradas e o eixo das
ordenadas corresponde ao tempo de execução ou espaço de memória utilizado.
A complexidade temporal mede a quantidade de tempo necessário para executar
um algoritmo com entrada de tamanho n (ZIVIANI, 2004). O problema dessa medição é que
o desempenho da execução do algoritmo é sensível ao software e ao hardware, podendo gerar
valores distintos em vários computadores.
A complexidade espacial mede o espaço de memória necessário para a execução
de um algoritmo com entrada de tamanho n (TOSCANI; VELOSO, 2005). O presente
trabalho utiliza-se dessa técnica, mais especificamente, do levantamento da quantidade de
instruções relevantes do algoritmo para fins de determinação do tempo de execução, cujo
intuito consiste em calcular a quantidade de instruções relevantes do algoritmo.
O
presente trabalho
utiliza-se,
mais especificamente, do levantamento da
quantidade de instruções relevantes do algoritmo para fins de determinação do tempo de
execução, introduzindo na ferramenta um mecanismo para realização desta contagem.
Para realizar a apresentação desta seção, dividiu-se o conteúdo em duas
subseções, a saber, pseudocódigo e contagem de operações primitivas. Na primeira, é
apresentado o modo como os algoritmos são representados neste documento. Na segunda, é
23
apresentado um modelo de contagem de instruções primitivas do pseudocódigo para cálculo
da complexidade algorítmica.
3.1
Pseudocódigo
Pseudocódigo é um código de alto nível escrito em linguagem natural, que
permite compreender facilmente a estrutura de um algoritmo. É um misto de linguagem
natural com estruturas comuns de programação, permitindo que outras pessoas não habituadas
com programação entendam o funcionamento do algoritmo (GOODRICH; TOMASSIA,
2004).
Goodrich et Tomassia (2004) estabeleceram um conjunto de notações para as
construções de linguagens de programação no pseudocódigo:
 Declaração do algoritmo: Algoritmo nome (parâmetro 1, parâmetro 2,...) declara um
nome para o algoritmo e os seus respectivos parâmetros.
 Operadores relacionais: o operador de atribuição igual (=) será usado para denotar
relação de igualdade em expressões booleanas. Para atribuição, utilizaremos a seta à
esquerda (←). Os demais operadores relacionais permanecem inalterados.
 Operadores lógicos: utiliza-se a linguagem natural desses operadores. Exemplo: e para
o operador (&&), ou para o operador (||), e não para operador de negação (~).
 Operadores aritméticos não utilizam nenhuma notação específica, apenas mantém a
notação atual.
 Laços: faça ações enquanto [condição]; para [atribuição de variável] [condição de
saída] passo [incremento] ações; faça enquanto [condição] ações. Usa-se tabulação
para delimitar as ações do laço.
 Indexação: A[i] representa um arranjo de i elementos, que contém posições que
variam de 0 até i-1.
 Estruturas de decisão: se [condição] então ações. Utiliza-se tabulação para amarrar as
ações às estruturas de decisão. Dadas às estruturas acima definidas, apresenta-se a
figura 1 como um exemplo de pseudocódigo:
24
Figura 1 - Exemplo de Pseudocódigo do Algoritmo Bolha
Analisando o pseudocódigo da figura 1, fica fácil entender o seu funcionamento.
No primeiro fluxo de execução, quando i e j são iguais à zero, o primeiro elemento do vetor é
comparado com o segundo elemento do vetor. Caso a comparação seja verdadeira (linha 3),
trocam-se os elementos da primeira e segunda posições do arranjo (linhas 4 a 6). A partir daí,
são feitas trocas sucessivas, caso sejam necessárias, até que se atinja o valor de (n-1)2
iterações, quando o vetor já estará ordenado.
Após
estabelecer
normas
para
representação
de
algoritmos
através
do
pseudocódigo, resta agora aplicar um modelo de contagem de instruções de código do
algoritmo, que será descrito no item seguinte.
3.2
Contagem de Operações Primitivas
Esse modelo baseia-se na contagem de operações primitivas do algoritmo. Cada
linha do algoritmo é analisada contando-se as operações primitivas, cujo somatório é o tempo
de execução do algoritmo T(n). De acordo com GOODRICH et TOMASSIA (2004), as
operações abaixo são consideradas operações primitivas:

Atribuições;

Chamada a métodos;

Comparações;

Operações aritméticas;
25

Acesso a um vetor;

Retornos;

Referências a objetos.
Tome-se como base o algoritmo da figura 1 para exemplificar o uso desse modelo.
Nela se pode observar que na linha 1 existe uma atribuição à variável i antes de entrar no
primeiro laço, o que corresponde a uma operação primitiva. Nessa mesma linha, duas
operações primitivas são feitas n vezes cada uma, devido à expressão i < n-1: operação
aritmética e comparação, contribuindo com 2n operações primitivas. O corpo do código do
primeiro laço para executa n-1 vezes. Então, a variável i é incrementada e atribuída,
somando 2(n-1) para a contagem.
Na linha 2, a variável j recebe o valor zero, cuja atribuição é repetida n-1 vezes.
Analisando somente a subtração e a comparação do termo j < n-1, ela executa 2n vezes. Mas
como essa comparação pertence ao corpo do primeiro para, então contribui com 2n(n-1)
unidades. O corpo do segundo laço para, é executado (n-1)(n-1) vezes. Atribuição e
incremento à variável j no final da iteração do segundo laço somam 2(n-1)(n-1) operações
primitivas.
A linha 3 contém uma operação aritmética, dois acessos a vetores e uma
comparação, totalizando 4(n-1)(n-1) operações primitivas.
Na linha 4, é realizada indexação ao acessar o arranjo V[j] e atribuição à variável
k, somando 2(n-1)(n-1) unidades para contagem.
Na linha 5, há uma operação aritmética j+1, acesso a um vetor V[j+1], acesso ao
vetor V[j] e atribuição a este de V[j+1], podendo contribuir com 4(n-1)(n-1) unidades.
Na linha 6, 3(n-1)(n-1) operações primitivas são possíveis: soma de dois números
j+1, acesso ao arranjo V[j+1] e atribuição de k.
Assim sendo, o corpo do segundo laço pode ter de 6(n-1)(n-1) a 15(n-1)(n-1)
operações primitivas. Portanto, a quantidade de operações primitivas t(n) feitas pelo algoritmo
bolha é no mínimo 1+ 2n + 2(n-1) + n-1 +2n(n-1) + 6(n-1)(n-1) = 8n2 - 9n + 4 e no máximo
6n2 - 9n + 4 + 9(n-1)(n-1) = 17n2 - 27n + 13.
26
O melhor caso t(n) = 8n2 - 9n + 4 acontece sempre quando o corpo da linha 3 não
é executado, ou seja, quando os elementos do vetor V estão em ordem decrescente. O pior
caso ocorre quando os elementos de V estão em ordem crescente.
A grande desvantagem na abordagem desse modelo é o grande dispêndio ao
separar e contar as operações primitivas num código, visto que existem algoritmos com
centenas e até milhares de linhas de código.
Na próxima seção será descrito a análise de algoritmos para entradas maiores e as
notações comuns de complexidade de algoritmo.
3.3
Análise Assintótica
A análise assintótica consiste no estudo do tempo de execução do algoritmo
conforme o aumento do tamanho da entrada (CORMEN et al., 2002).
Para entradas menores, o custo de execução de um algoritmo é baixo. Porém,
quando n aumenta indefinidamente, pode-se mostrar os limites do custo de execução do
algoritmo sobre n.
A tabela 1, encontrada na obra de Toscani et Veloso (2005), mostra as diferenças
de desempenho entre os algoritmos de Crammer e Gauss para resolução de um sistema de
equações lineares de tamanho n.
Tabela 1 - Tamanho do Problema x Tempo de Execução
n
2
3
4
5
10
20
40
Mé todo de Cra mmer
22 µs
102 µs
456 µs
2.35 ms
1.19 mi n
15225 sé culos
5x1033 sé culos
Mé todo de Gauss
50 µs
159 µs
353 µs
666 µs
4.95 ms
38.63 ms
0.315 s
27
A tabela 1 denota que, para entradas menores, os métodos de Crammer e Gauss
possuem uma diferença mínima no tempo de execução. Entretanto, quando n aumenta
consideravelmente, o algoritmo de Crammer vai deixando de ser aceitável na prática.
3.3.1
Notação O
Segundo Goodrich et Tomassia (2004), uma função f(n) é considerada O(g(n)) se
f(n) e g(n) são funções que englobam números inteiros e existe uma constante real c > 0 e uma
constante inteira n0 ≥ 1, de tal sorte que f(n) ≤ cg(n) para todo inteiro n ≥ n0 . A figura 2 ilustra
essa definição:
Figura 2 - Notação O. Fonte (GOODRICH; TOMAS S IA, 2004)
A partir do ponto n0 , a função f(n) nunca ultrapassará a função cg(n). Assim
sendo, cg(n) domina assintoticamente f(n), ou seja, g(n) é o limite assintótico superior
(CORMEN et al., 2002).
Toma-se como exemplo o tempo de execução do pior caso do algoritmo da figura
1. A função f(n) = 17n2 - 27n + 13 é O (n2 ), pois 17n2 - 27n + 13 ≤ 17n2 , cuja constante c =
17 para todo n0 ≥ 1.
28
3.3.2
Notação Ω
Ao contrário da notação O, a notação Ω (ômega) limita por baixo a função f(n).
Segundo Toscani et Veloso (2005), uma função f(n) é Ω(g(n)), quando f(n) e g(n) são funções
que englobam números inteiros e existe uma constante c > 0 e n0 > 0 tal que, f(n) ≥ cg(n). A
figura 3 representa bem essa definição:
Figura 3 - Notação Ω. Fonte(TOS CANI; VELOS O, 2005)
Para exemplificar, toma-se o polinômio do melhor caso do algoritmo bolha,
definido na seção 3.2. Para mostrar que f(n) = 8n2 - 9n + 4 é Ω(n2 ), basta fazer c = 7 e n0 ≥ 9
para que a condição (8n2 - 9n + 4) ≥ 7n2 seja verdadeira. No entanto, como essa notação
denota que a função f(n) crescerá no mínimo igual à função g(n), é correto afirmar que o
melhor caso do algoritmo bolha é Ω(n2 ), pois o segundo laço é executado, mesmo sendo no
melhor caso. Assim, tanto a notação O quanto a notação Ω possuem complexidade quadrática.
O algoritmo insertion sort citado por CORMEM et al. (2002), por exemplo,
demonstra que a complexidade O difere da Ω. O pior caso desse algoritmo é O(n2 ), enquanto
que o melhor caso é representado por uma função linear Ω(n), quando o vetor já se encontra
ordenado.
29
3.3.3
Notação Θ
Conforme Ziviani (2004), f(n) é dito ordem de Θ(g(n)) se existirem três constantes
positivas c1 , c2 e n0 tal que, c1 g(n) ≤ f(n) ≤ c2 g(n) para n ≥ n0 . Apresenta-se a figura 4 como
exemplo dessa notação:
Figura 4 - Notação Θ. Fonte(ZIVIANI, 2004)
Na figura acima, a partir de n0 percebe-se que a função f(n) é delimitada por uma
região compreendida entre as funções g(n). Assim, g(n) é considerado limite assintótico
restrito (CORMEN et al., 2002). A função 5n2 é Θ(n2 ), pois c1 n2 ≤ 5n2 ≤ c2 n2 produz c1 ≤ 5 ≤
c2 .
No capítulo seguinte, serão apresentados os requisitos da ferramenta com base nos
conceitos de engenharia de software, a arquitetura adotada e as tecnologias utilizadas no
desenvolvimento do sistema.
30
4.
DESENVOLVIMENTO DA APLICAÇÃO
Neste
capítulo,
serão
discutidos
os
seguintes
aspectos
relacionados
ao
desenvolvimento do sistema: requisitos do sistema, arquitetura, ambiente de desenvolvimento
e tecnologias empregadas.
4.1
Requisitos do Sistema
Os requisitos de um sistema de software denotam uma função ou restrição do
sistema e são classificados da seguinte forma (SOMMERVILLE, 2003):

Requisitos funcionais: tratam das funções e comportamentos do sistema em
determinadas situações.

Requisitos não funcionais: definem restrições de qualidade para o sistema em
termos de desempenho, confiabilidade, usabilidade, portabilidade, etc.

Requisitos de domínio: são requisitos provenientes do domínio de aplicação do
sistema e que refletem propriedades deste campo. Podem ser requisitos funcionais
ou não funcionais.
Nas subseções seguintes, serão apresentados os requisitos da ferramenta
implementada neste trabalho, que tem por objetivo calcular a complexidade de um algoritmo
passado pelo usuário e mostrar os resultados graficamente com base no cálculo de operações
primitivas.
31
4.1.1
Requisitos Funcionais

O software deve analisar somente algoritmos escritos em Java.

A aplicação deve permitir a utilização de algoritmos recursivos ou iterativos.

O cálculo de complexidade será feito a partir da contagem de operações primitivas,
conforme descrito na seção 3.2.

Os resultados do cálculo de complexidade deverão ser visualizados em um gráfico
para facilitar a leitura das informações.
4.1.2
Requisitos não Funcionais
Os principais requisitos não funcionais identificados para a ferramenta são
apresentados a seguir.

Usabilidade
a. A interface da aplicação deve ser simples, organizada e legível, permitindo que os
usuários sintam-se à vontade para manusear o software.
b. A aplicação deve incluir ferramentas para facilitar a edição e visualização de
código.
c. O sistema deve notificar o usuário sobre quaisquer erros de codificação ou erros
grosseiros de utilização.
d. Um módulo de ajuda deve estar acessível e legível para o usuário, e deve guiá-lo
para uma correta utilização do software.

Confiabilidade
Em caso de falha de compilação de código ou de qualquer evento anormal, o
sistema deve se recuperar.
32

Portabilidade:
A aplicação poderá ser executada em qualquer sistema operacional com uma
máquina virtual Java instalada.
4.2
Arquitetura
Para um melhor entendimento da arquitetura do sistema, será apresentado,
primeiramente, um diagrama de atividade que ilustra a lógica principal da aplicação.
Figura 5 - Diagrama de atividade da lógica geral da aplicação
33
Na figura 5, percebe-se que inicialmente a aplicação recebe do usuário o código
escrito em Java para a geração das entradas que serão computadas por um algoritmo. Em
seguida, o sistema processa a entrada, o algoritmo e constrói uma classe contendo uma rotina
que alimenta o algoritmo com as entradas. No próximo passo, o sistema compila a classe e,
caso não haja erros, executa-a. Os dados resultantes da execução da classe são coletados e
impressos em um gráfico. Todo o processo a partir da atividade de processamento da entrada
é refeito enquanto existirem entradas a serem computadas. Por fim, quando todas as entradas
são processadas, a atividade da aplicação termina e caminha para o estado final.
Entendido o funcionamento geral do sistema, a próxima subseção abordará a
arquitetura adotada pelo sistema.
4.2.1
Modelagem Arquitetural
Na modelagem arquitetural da ferramenta, foi utilizado o MVC (Model View
Controller) (ECKSTEIN, on-line), um padrão arquitetural que separa a lógica de negócio da
camada de apresentação. O MVC foi introduzido em 1979, sendo inicialmente aplicado para
desenvolvimento em Smalltalk. Sua implementação ajudou a desacoplar a lógica de negócio
da maneira com que os dados são vistos pelo usuário. A arquitetura MVC divide-se em três
camadas:
 Modelo(Model): Representa a lógica de negócio da aplicação, ou seja, a utilização dos
dados da aplicação para agregar funções do domínio do sistema.
 Visão(View): Representa a camada que interage com o usuário. É através dela que o
usuário visualiza ou submete os dados ao sistema.
 Controlador(Controller): É camada que traduz a interação do usuário com a visão em
ações que o modelo irá executar.
A figura 6 ilustra a utilização do padrão MVC na modelagem das principais
classes do sistema e os seus relacionamentos.
34
Figura 6 - Diagrama de classe da aplicação
Fragmentando a figura 6 com base no padrão MVC, percebe-se que o controlador
corresponde à classe preenchida com a cor amarela. As visões do sistema são as classes
preenchidas com a cor azul. As demais classes ilustradas pela cor verde correspondem ao
modelo. A tabela 2 descreve de forma sucinta as classes do sistema.
35
Tabela 2 - Descrição das classes do sistema
Classe
View
LineChartView
Controller
TamanhoEntrada
AnnotationControl
Allocator
ManipStr
Compiler
Counter
Runner
Descrição
Tela principal da aplicação.
Tela do gráfico resultante da análise do
algoritmo.
Controlador da aplicação. Traduz as ações
do usuário em funções do sistema.
Classe que define uma palavra reservada
para recepção dos tamanhos e tipo das
entradas do algoritmo.
Classe que carrega os valores e o tipo das
entradas da classe TamanhoEntrada.
Classe que aloca tamanhos e valores para
um tipo de dado especificado na classe
TamanhoEntrada.
Classe que prepara uma estrutura de uma
classe ConcreteRunner em uma String.
Classe que grava a String da classe
ConcreteRunner em um arquivo .java,
compila e executa.
Classe que computa as operações primitivas
para cada entrada.
Interface que define um método comum a
um ConcreteRunner.
Na camada da visão, a classe View corresponde à tela principal da aplicação. É
através dela, por exemplo, que o usuário insere o código fonte de um algoritmo e solicita
ações para análise de complexidade com base no cálculo de operações primitivas. A classe
LineChart é responsável pela exibição gráfica dos resultados da análise de complexidade.
Na camada de controle, a classe Controller intercepta requisições do usuário
vindas da camada de visão e solicita o processamento das requisições às classes pertencentes
ao modelo.
No modelo, a classe ManipStr é responsável pela recepção do código do usuário e
preparação para que o mesmo seja compilado e executado posteriormente na classe
ConcreteRunner.
36
A classe TamanhoEntrada define uma anotação para uma palavra reservada do
sistema, cuja função é alocar tamanhos e valores para as entradas que serão utilizadas na
execução do algoritmo onde as operações serão contadas. Essa anotação atua sobre campos
Java e possui uma política de retenção Runtime (ORACLE, on-line).
A classe AnnotationControl fornece métodos de controle e de recuperação de
dados da anotação. Como os dados só são retidos em tempo de execução utiliza-se a técnica
Reflection para recuperação dos dados referentes às entradas.
A classe Allocator aloca tamanhos e atribui valores aleatórios para um tipo de
dado definido na anotação TamanhoEntrada. Os seguintes tipos são suportados:
 Primitivos e seus arrays: int, float, long, double, char.
 Classes Wrappers e seus arrays: Integer, Float, Long, Double, String, Character.
A classe Compiler possui funções especiais como compilação e execução da
classe construída pelo sistema (ConcreteRunner). Na compilação, utiliza-se a interface
JavaCompiler (ORACLE, on-line), para compilar um arquivo a partir de um programa Java.
Na execução, carrega-se a classe ConcreteRunner utilizando um ClassLoader próprio e
executa esta classe por meio de Reflection.
37
Figura 7 - Diagrama de Sequência da Aplicação
A classe ConcreteRunner é sempre alterada com o código passado pelo usuário,
compilada e executada. Ela implementa o método run(int x) da interface Runner. Esse método
recebe por parâmetro o valor de cada entrada a ser processada pelo conteúdo interno
(algoritmo do usuário). A implementação da interface possibilita que a classe ConcreteRunner
sempre seja vista como um tipo de Runner pelo sistema, ou seja, o sistema invocará métodos
da classe por meio de sua interface. Essa classe, também herda métodos de controle da
contagem de operações primitivas da classe Counter, que podem ser empregados em sua
estrutura. A herança permite gerenciar a contagem de operações primitivas por meio da
superclasse. A figura 7 ilustra uma sequência típica de troca de mensagens entre estas classes.
Compreendida a arquitetura e a função de cada componente do sistema, serão
apresentadas nas subseções seguintes uma descrição do ambiente de desenvolvimento da
aplicação e as principais tecnologias empregadas.
38
4.3
Ambiente de Desenvolvimento
Para o desenvolvimento do sistema, foi utilizado o IDE NetBeans 6.9.1 Java
SE(Standart Edition) (NETBEANS, on-line).
Esta distribuição inclui ferramentas essenciais
para programação em Java como: editor, perfil, suporte à refatoração e um módulo de
desenvolvimento gráfico.
Além disso, a ferramenta de desenvolvimento dispõe de um editor gráfico de
componentes da biblioteca swing, permitindo construir aplicações desktop de forma rápida,
apenas arrastando e soltando os componentes na tela.
4.4
Tecnologias Empregadas
Foi utilizada a linguagem Java tanto para o desenvolvimento da ferramenta quanto
para a especificação dos algoritmos que serão analisados através da mesma. Além de ser uma
linguagem robusta e bem estabelecida no mercado, para a qual existe uma extensa gama de
bibliotecas e frameworks, o Java é adotado na grande maioria dos cursos de computação como
padrão para o ensino de técnicas de programação, o que pode suavizar a curva de aprendizado
dos usuários durante o uso da ferramenta.
Nos próximos subitens serão abordadas as principais tecnologias e bibliotecas da
linguagem Java empregadas na implementação da ferramenta.
4.4.1
Reflection
Reflection é um recurso que permite que um programa Java examine ou faça
introspecção de si mesmo (MCCLUSKEY, on-line). Está presente na linguagem Java desde a
versão 1.1 e é através dela que conseguimos visualizar os membros de uma classe, invocar
métodos e até instanciar classes dinamicamente.
Esta tecnologia é utilizada frequentemente na implementação de funções como
code-completion (figura 8), presente nos softwares de desenvolvimento, onde o programador
39
consegue visualizar os membros de uma classe usando o operador ponto (.), após a declaração
da classe ou instância da mesma. A figura 8 mostra uma lista de métodos da classe String que
podem ser visualizados em tempo de codificação, graças ao Reflection, ilustrando bem um
exemplo de utilização.
Figura 8 - Exemplo code-completion no Netbeans
Este recurso também permite a instanciação de classes e a utilização de seus
membros (métodos ou variáveis de instância), apenas declarando o nome da classe. A figura 9
ilustra esta outra situação.
Figura 9 - Exemplo de instância de classe e execução de método via Reflection
Na primeira linha, foi declarado o nome da classe que se deseja examinar. A
classe em questão é empregada para criar estruturas do tipo Hash.
Na segunda linha, foi definido o método para execução chamado size que contém
um argumento nulo.
40
Na terceira linha, a classe é instanciada e, na última linha, o método é invocado
passando um argumento nulo.
O emprego de Reflection no projeto permitiu instanciar a classe ConcreteRunner e
invocar os seus métodos dinamicamente, além de coletar os valores passados para as
anotações.
4.4.2
Annotation
Desde a versão 5.0, o Java oferece suporte a uma anotação de proposito geral, a
fim de tornar o desenvolvimento mais ágil e eficiente (ORACLE, on-line). As anotações se
comportam como metadados, ou seja, dados que descrevem outros dados. Elas não afetam a
semântica do programa em execução, mas influenciam como os programas são tratados por
ferramentas e bibliotecas.
Na definição de uma anotação, acrescenta-se um sinal “arroba” (@) antes da
palavra reservada interface seguido de um nome para a anotação. As anotações podem ser
definidas nas seguintes estruturas:
 ElementType.Type – Aplicada apenas ao tipo. Um tipo pode ser uma classe, interface,
enum ou até mesmo uma anotação.
 ElementType.Field – Campos Java.
 ElementType.Method – Métodos.
 ElementType.Parameter – Parâmetros dos métodos.
 ElementType.Constructor – Construtores das classes.
 ElementType.Package – Pacotes.
 ElementType.Annotation_Type – Declaração de um tipo de anotação.
Uma retention policy (política de retenção) pode ser adotada para definir o
domínio de recuperação dos dados da anotação. As políticas de retenção são as seguintes:
 RetentionPolicy.Source – Este tipo de anotação pode ser retida a nível de código fonte,
porém a anotação é ignorada pelo compilador.
41
 RetentionPolicy.Class – As informações são retidas em tempo de compilação, mas não
estão visíveis pela máquina virtual Java.
 RetentionPolicy.Runtime - A anotação é retida somente em tempo de execução pela
máquina virtual Java.
No projeto, uma anotação foi criada sobre uma variável de instância com retenção
em tempo de execução, para dar suporte a uma expressão reservada do sistema que será vista
mais adiante.
4.4.3
ClassLoader
Através da compilação de arquivos de código fonte Java, gera-se arquivos de
extensão .class, cujo conteúdo (bytecodes) é processado pela JVM (Java Virtual Machine). A
JVM acessa os bytecodes através do ClassLoader (SILVEIRA, on-line).
Toda classe Java é carregada por alguma instância de ClassLoader. Esta classe é
encontrada no pacote java.lang e serve tanto para o carregamento de classes definidas pelo
usuário quanto para o carregamento das classes essenciais da linguagem. A figura 10 ilustra a
hierarquia do ClassLoader:
Figura 10 - Hierarquia do ClassLoader. Fonte(http://www.developer.com/img/articles/2003/08/14/cl_hierarchy.gif)
Na figura 10, os elementos abaixo da hierarquia carregam classes somente se
tentativas de carregamento forem delegadas para os elementos acima da hierarquia
42
(TAYLOR, on-line). A JVM possui um carregador de classe em sua implementação chamado
Bootstrap ClassLoader, que é responsável pelo carregamento de classes confiáveis da
linguagem como (java.*, javax.* ). O Extension ClassLoader carrega as classes do diretório
do JRE (java runtime environment). Por último, o System ClassLoader é responsável pelo
carregamento de classes do classpath do sistema.
A escrita de um próprio ClassLoader no projeto permitiu o carregamento
dinâmico da classe que é sempre compilada e executada (ConcreteRunner). É uma classe
externa ao sistema, pois não se encontra no diretório padrão dos fontes da aplicação. Caso
fosse
uma
classe
interna,
existiria
a
possibilidade
de
erros
de
compilação
e,
consequentemente, a execução da aplicação seria comprometida. Por isso, foi necessário
escrever um próprio ClassLoader para esta classe.
4.4.4
JSyntaxPane
É um simples editor de código feito em Java. Suporta as seguintes linguagens:
Java, JavaScript, Properties, Groovy, C, C++, XML, SQL, Ruby e Python (JSYNTAXPANE,
on-line). Possui um conjunto de ferramentas que facilitam a edição de código, além de realçar
as palavras reservadas da linguagem ou qualquer expressão. A utilização deste editor
contribuiu para melhorar a usabilidade da ferramenta, já que facilita a visualização e a edição
de código.
Figura 11- JSyntaxPane
43
Nativamente o componente já vem com vários recursos como: recortar, copiar, colar,
desfazer, refazer, localizar e substituir, adicionar e remover comentários do código.
4.4.5
JFreeChart
O JFreeChart (JFREECHART, on-line) é um software livre que possibilita aos
desenvolvedores incluir gráficos de qualidade em suas aplicações. Ele dispõe de uma vasta
quantidade de gráficos que podem ser incluídos em componentes swing ou impressos em
formato PNG, JPEG, PDF, EPS e SVG. A figura 12 mostra um exemplo de um gráfico desta
API.
Figura 12 – IlustraçãoJ Linechart (JFreeChart)
Um gráfico do tipo LineChart (figura 12) foi adotado no projeto para exibição dos
dados referentes à análise do algoritmo.
44
4.4.6
PDFHelp
Para criação de uma tela de ajuda para aplicação, utilizou-se o plugin e
componente do NetBeans chamado PDFHelp (PDFHELP, on-line), baseado na visualização
de arquivos PDF, ilustrado pela figura 13.
Figura 13 - Integração do PDFHelp no Netbeans
É uma ferramenta de fácil utilização e manutenção. Possui as principais
características de um leitor de arquivos PDF, como paginação, pesquisa, zoom, etc. O
conteúdo de ajuda é escrito em arquivos PDF e o desenvolvedor apenas define para o
componente quais arquivos devem ser listados. O componente incrementa a usabilidade da
aplicação, já que fornece mecanismos para buscas de informações e instruções de uso da
ferramenta.
45
5. UTILIZAÇÃO DA FERRAMENTA
Este capítulo tem por objetivo apresentar o funcionamento da ferramenta. A seção
está dividida em três partes: interface, palavras reservadas e exemplos de funcionamento da
aplicação.
5.1
Interface
A figura 14 ilustra a tela principal da aplicação. Cada componente ou conjunto de
componentes estão envolvidos por um retângulo vermelho seguido de uma numeração e serão
abordados a seguir:
46
Figura 14 - Tela principal da aplicação
1. Barra de Menu
No menu Arquivo existe apenas o submenu Sair, cuja função permite sair do
sistema. No menu Help, encontra-se o manual de utilização da aplicação, como visto na figura
15:
47
Figura 15 - Help da aplicação
A figura 15 ilustra o módulo de ajuda da aplicação suportado pela API PDFHelp
apresentada na seção 4.4.6.
2. Barra de Ferramentas
Aqui se encontram as ferramentas que facilitam a edição de código na aplicação.
Os botões que merecem destaque são: recortar, copiar, colar, desfazer, refazer, comentar,
localizar e substituir código.
3. Editor de Código:
É o local onde são escritos o código de geração das entradas e o algoritmo para
cálculo de complexidade. Divide-se em duas abas: Geração das Entradas e Contagem de
Operações. A aba de geração das entradas permite o desenvolvimento do código de geração
das entradas que serão passadas para o algoritmo, que será fornecido na aba de contagem de
operações.
48
A aba de contagem de operações pode receber tanto implementações de
algoritmos em métodos quanto em classes. Nesta aba, são permitidas importações de classes,
mas não são permitidas declarações de pacotes.
4. Contador de Linhas
O quarto componente exibe o total de linhas do código e a numeração da linha
que se encontra o cursor.
5. Botão Executar
A função deste botão é acionar a análise de operações relevantes do algoritmo no
editor de código, indicadas pelo usuário, cujos resultados serão exibidos graficamente.
6. Saída de Erros
Notifica eventuais erros de compilação de código.
5.2
Palavras Reservadas
Neste tópico, serão descritas as palavras reservadas do sistema, que são
fundamentais para construção do código para a análise da complexidade. As seguintes
palavras reservadas serão destacadas de cor vermelha no editor de código fonte ilustrado nas
figuras 16 e 17.
 @TamanhoEntrada(tam={val1, val2, val3,...})<tipo de dado><nome>;
Trata-se de uma anotação que recebe números inteiros positivos (val1, val2, val3,...)
como entrada e aloca tamanhos e valores para um tipo de dado definido. Essa expressão
facilita a criação das entradas com valores aleatórios para o algoritmo, permitindo que o
usuário não tenha o trabalho tedioso de instanciar e atribuir valores para um tipo de dado.
Deve ser declarada na aba de geração das entradas no editor de código e sempre deve ser
escrita antes da expressão #main, que será vista mais adiante. A figura 16 mostra como deve
ser a declaração desta palavra reservada.
49
Figura 16 - Escrita da expressão @TamanhoEntrada
Na figura 16, a variável inteira x receberá os valores 1, 2 e 3, respectivamente.
Outros tipos de dados são suportados, tais como:
a) Primitivos: int, float, long, double, char e seus respectivos arrays.
b) Classes Wrapper: Integer, Float, Long, Double, Character, String e seus respectivos
arrays.
 #main
É uma expressão da aplicação que separa a declaração da palavra reservada
@TamanhoEntrada da chamada do algoritmo que se encontra na aba de contagem de
operações. Deve ser declarada sempre após a definição da anotação @TamanhoEntrada.
 @contar(int x)
Serve para computar as operações relevantes de um algoritmo. Recebe um
parâmetro inteiro opcional que corresponde ao número de vezes que uma operação é
incrementada. Deve ser declarada no escopo da operação primitiva que se deseja computar na
aba de contagem de operações.
50
Figura 17 - Escrita da expressão @contar
5.3
Exemplos
Nesta seção, serão abordados três exemplos de algoritmos para ilustrar o emprego
das palavras reservadas e o funcionamento do cálculo de operações relevantes no software.
5.3.1
Exemplo 1
O primeiro exemplo consiste de um algoritmo contendo apenas uma estrutura do
tipo laço. Todas as operações primitivas serão computadas para fazer um comparativo com a
teoria de operações relevantes vista na seção 3.2.
Figura 18 - Geração das entradas Exemplo 1
Na figura 18, foram definidas as entradas de tamanho 1, 2 e 3 utilizando a palavra
reservada @TamanhoEntrada que serão armazenadas pela variável x (linha 2). Na linha 4,
51
definiu-se a expressão #main para separar o código de geração das entradas da chamada do
método contagem(x). Esse método é chamado três vezes, passando por parâmetros os valores
1, 2 e 3, respectivamente. A estrutura do método é encontrada na aba Contagem das
Operações, ilustrado pela figura 19:
Figura 19 - Contagem das operações Exemplo 1
No método da figura 19, encontramos uma estrutura do tipo laço delimitada pelas
linhas 4 e 11. Na linha 4, antes do primeiro laço ser computado, uma operação primitiva é
feita devido à atribuição i = 0. No escopo do laço, são realizadas n operações primitivas,
correspondente a expressão i<tam e 2n operações são feitas com base na atribuição e
incremento da variável i.
Uma última operação relevante é computada quando a expressão i<tam for falsa.
Assim, no total temos 1 + n + 2n + 1 = 3n + 2 operações primitivas, onde n corresponde à
entrada do algoritmo.
As linhas 3, 6, 8, 10 e 13 retratam pontos de contagem de operações relevantes
indicados pelo usuário através da palavra reservada @contar. Neste caso, os pontos de
contagem refletem a complexidade de operações relevantes 3n + 2, calculado anteriormente.
Ao executar o processamento do algoritmo, obtém-se o seguinte gráfico:
52
Figura 20 - Gráfico Exemplo 1
A figura 20 mostra a relação entre a entrada passada pelo usuário e o cálculo de
operações primitivas do código. Aplicando o valor da primeira entrada na equação de
complexidade 3n + 2, obtém-se o valor 3(1) + 2 = 5, que é valor o correspondente à
quantidade de operações primitivas na ordenada.
Na segunda entrada, temos 3(2) + 2 = 8 operações relevantes. Por último, na
terceira entrada, temos 3(3) + 2 = 11. Assim sendo, prova-se que a aplicação está contando
todas as operações primitivas para o exemplo em questão.
5.3.2
Exemplo 2
Neste exemplo, será abordado como é feita a definição e instanciação de classes
Java na aplicação. Apresenta-se, primeiramente, o código da contagem das operações na
figura 21.
53
Figura 21 - Contagem das operações Exemplo 2
O código da figura 21 tem a função de percorrer um array de Integer e adicionar
os números pares em uma lista. O software suporta a importações de classes comuns da
linguagem, como também classes do usuário no classpath do Java.
Uma peculiaridade vista na linha 4 é que a classe Numero possui um modificador
de acesso padrão. Esta classe será declarada internamente na estrutura da classe
ConcreteRunner e pode ter também o modificador de acesso public.
A linha 8 ilustra à contagem de duas operações primitivas, passadas por parâmetro
para a expressão @contar(). Esta expressão computa as operações resto da divisão e
comparação, vistas na linha 9. A próxima figura mostra o código de geração das entradas.
Figura 22 - Geração das entradas Exemplo 2
54
Nas linhas 2 e 3 encontram-se a notação para definição das entradas para um
array de Integer. Em seguida, na linha 6, uma instanciação comum à linguagem Java. Por
fim, chama-se o método nPar pela instancia de Numero passando arrays de Integer, cujos
tamanhos são 7, 10, 14, 19, 56, 98, 103, 500, 1000, respectivamente. A figura 23 mostra o
gráfico da computação das operações relevantes do código.
Figura 23 - Gráfico Exemplo 2
4.3.3
Exemplo 3
O software não se limita a apenas algoritmos simples. Algoritmos mais robustos
como quicksort podem ser testados para verificar o comportamento da aplicação. A figura 24
ilustra a implementação do quicksort:
55
Figura 24 - Contagem das operações Exemplo 3
Na figura 24, percebe-se que conta-se a quantidade de comparações do primeiro
laço, linha 18. A linha 17 computa a última comparação do laço, quando i <= j for falso. A
linha 19 conta quantas vezes a expressão i <= j é verdadeira. Com base nas entradas da figura
25, obtém-se o gráfico ilustrado pela figura 26.
56
Figura 25 - Geração das entradas Exemplo 3
Figura 26 - Gráfico Exemplo 3
57
O Anexo A – Algoritmo Complementar dispõe de um algoritmo de busca em
árvore
binária,
exemplificando
o
funcionamento
da
ferramenta
em algoritmos mais
complexos.
O algoritmo da torre de hanoi, cuja complexidade é exponencial foi executado
sobre entradas grandes, a fim de verificar o funcionamento da aplicação sob stress. O
software obteve um desempenho aceitável e nenhum evento anormal foi observado.
58
6. AVALIAÇÃO DA FERRAMENTA NO CONTEXTO EDUCACIONAL
Neste capítulo, serão apresentados os resultados de uma pesquisa realizada para
verificar a aceitação da ferramenta pelos usuários. Divide-se em duas seções, a saber:
questionário e resultados.
6.1
Questionário
Foi elaborado um questionário com 10 perguntas como um meio de se obter um
feedback dos usuários. As perguntas buscam avaliar alguns critérios de software educacional
vistos na seção 2.1. Na tabela 3, se encontram as perguntas e as relações com os critérios de
software educacional.
59
Tabela 3 - Perguntas x Critérios
Pergunta
1) O sofware possui um design agradável e de fácil
leitura?
2) É fácil encontrar e manusear os componentes da
tela?
3) Consegue interpretar bem as informações na
representação gráfica do algoritmo?
4) Sente-se confuso com a quantidade de
informações na tela?
5) O editor de código facilita na codificação?





6) As expressões reservadas do sofware possuem 
um bom manuseio?

7) A tela de ajuda é clara e de boa leitura?

8) Localiza facilmente informações sobre utilização 
do software?
9) O sistema reage bem a erros grosseiros de 
utilização?
10) O software atende bem ao seu propósito?

6.2
Critérios
Interface: atrativo para grupos de
usuários; boa apresentação.
Qualidade: utilização simples de
suas funções essenciais.
Aprendizagem: fácil leitura.
Aprendizagem:
informações
reduzidas na tela.
Qualidade: utilização simples das
funções essenciais.
Qualidade: utilização simples das
funções essenciais.
Qualidade:
instruções
sobre
uso(help).
Aprendizagem: fácil leitura.
Interface: atrativo para grupos de
usuários; intuitivo.
Qualidade: reação a erros de
utilização.
Questão opinativa.
Resultados
O software desta obra foi apresentado brevemente para uma turma da disciplina
de Paradigmas de Linguagens de Programação do curso de Ciência da Computação da
Faculdade Farias Brito, composta por 13 alunos, os quais já tinham conhecimentos sobre
complexidade de algoritmos. Os alunos receberam instruções sobre o funcionamento da
ferramenta através de exemplos práticos de contagem de operações de algoritmos. Em
seguida, os alunos manipularam a aplicação e responderam um questionário com a finalidade
de se avaliar aspectos qualitativos da ferramenta e sua aceitação. Vale ressaltar que a pesquisa
foi feita junto a uma quantidade limitada de alunos e os resultados obtidos não foram
submetidos a um tratamento estatístico rigoroso. Portanto, estes devem ser encarados apenas
como um indicativo da adequação da ferramenta no que concerne aos critérios adotados. A
tabela 4 mostra os resultados da avaliação:
60
Tabela 4 - Resultado da avaliação do software
1) O software possui um
design agradável e de fácil
leitura?
2) É fácil encontrar e
manusear os componentes
da tela?
3) Consegue interpretar bem
as informações na
representação gráfica do
algoritmo?
4) Sente-se confuso com a
quantidade de
informações na tela?
5) O editor de código facilita
na codificação?
6) As expressões reservadas
do software possuem um
bom manuseio?
7) A tela de ajuda é clara e
de boa leitura?
8) Localiza facilmente
informações sobre
utilização do software?
9) O sistema reage bem a
erros grosseiros de
utilização?
10) O software atende bem ao
seu propósito?
Concordo
Fortemente
Concordo
Indeciso
Discordo
Discordo
Fortemente
54%
38%
8%
23%
62%
15%
46%
46%
8%
23%
16%
46%
15%
23%
61%
8%
8%
8%
46%
46%
46%
46%
8%
7%
77%
8%
8%
54%
31%
15%
54%
15%
31%
Na primeira questão, a maioria dos alunos sentiu-se atraída pela interface
principal da aplicação e conseguiu ler facilmente os componentes da tela. Apenas 8% dos
usuários tiveram dúvidas sobre este quesito.
Na segunda questão, 62% dos alunos concordaram com a facilidade de encontrar e
manusear funções essenciais da aplicação. Na terceira questão, 92% dos usuários pelo menos
61
concordam com a facilidade de interpretação das informações na representação gráfica da
análise do algoritmo.
Na quarta questão, 46% dos alunos discordam que a quantidade de informações
na tela prejudica a leitura. Na quinta questão, a maioria aprovou o componente de edição de
código da aplicação.
Na sexta questão, 54% dos usuários pelo menos concordam que as palavras
reservadas do sistema possuem um bom manuseio. Os outros 46% ficaram indecisos, o que
não deixa de ser um resultado ruim neste quesito, já que leva-se um certo tempo para
familiarização com as expressões reservadas da aplicação.
Na sétima questão, 92% dos alunos concordam e concordam fortemente que o
módulo de ajuda da aplicação é claro e legível. Na questão seguinte 77% dos usuários
concordam com a facilidade busca de informações da tela de ajuda.
A nona questão denota que 54% dos alunos concordam que a aplicação reage bem
a erros grosseiros de utilização. Por último, na décima questão, os usuários aprovaram a
ferramenta com 85% de aceitação, demonstrando que a mesma pode servir como um
instrumento agregador no ensino de complexidade algorítmica.
62
7.
CONCLUSÃO
O estudo de complexidade de algoritmos envolve conceitos não triviais e carece
de uma maior atenção e dedicação do aluno. Softwares educacionais podem auxiliar no
aprendizado, possibilitando o experimento de conceitos através de exemplos práticos.
Este trabalho teve por objetivo desenvolver uma aplicação que calcule a
complexidade de um algoritmo escrito em Java e exibir a curva de complexidade, servindo de
auxílio no ensino de complexidade algorítmica.
O trabalho levantou a questão da inserção da informática na educação, onde o
computador é programado para ensinar e ser ensinado. Critérios de softwares educacionais,
como
qualidade,
interface e resultados de aprendizagem foram apresentados como
características intrínsecas de um bom software educacional.
Foram abordados os principais conceitos de complexidade de algoritmos e
introduzidas às notações que exprimem limites de crescimento dos custos dos algoritmos.
Uma metodologia para análise de algoritmos foi definida, baseada na contagem de operações
primitivas.
O processo de desenvolvimento do software, guiado pelo modelo de contagem de
operações primitivas e pelos critérios de softwares educacionais, envolveu a definição de
requisitos, arquitetura, ambiente e tecnologias empregadas no desenvolvimento.
Vários exemplos de utilização foram criados para ilustrar o funcionamento da
ferramenta e realizar uma avaliação de sua interface visual.
63
A ferramenta foi apresentada para uma pequena turma do curso de Ciência da
Computação da Faculdade Farias Brito. Os alunos manusearam a aplicação e avaliaram a
ferramenta através de um questionário que envolve critérios de software educativo. Com base
nos resultados da avaliação, percebeu-se que os alunos tiveram uma boa impressão da
ferramenta, mostrando que ela tem potencial de ser empregada como ferramenta pedagógica.
Como trabalho futuro, pode-se buscar a implementação de um mecanismo de
análise automática de algoritmos, ou seja, o próprio sistema detecta e conta as operações
primitivas. Assim, livra-se o usuário do trabalho tedioso de separar e contar as operações
relevantes do código.
Outra sugestão seria a possibilidade do usuário definir uma equação que
representa
uma
função
de
complexidade
que
pudesse
ser
visualizada
no
gráfico
conjuntamente com a curva gerada através da contagem, permitindo ao usuário comparar o
gráfico da contagem de operações primitivas com um gráfico de crescimento assintótico, por
exemplo.
O presente trabalho contribuiu como mais um software que se preocupa em
utilizar
conceitos
pedagógicos,
além de fomentar o
desenvolvimento
de aplicativos
educacionais para auxiliar ou complementar no estudo de disciplinas que exigem mais
dedicação.
64
REFERERÊNCIAS BIBLIOGRÁFICAS
BORGES, M.A.F. Aprendizagem e avaliação em um curso à distância. Colabora - Revista
Digital da CVA-RICESU, v.1, n. 3, fevereiro 2002. 8 pags.
CORMEN, Thomas H.; LEISERSON, Charles E.; RIVEST, Ronald L; STEIN, Clifford.
Algoritmos: teoria e prática. Tradução da segunda edição americana por Vandenberg D. de
Souza. Rio de Janeiro: Elsevier, 2002.
ECKSTEIN,
Robert.
Java
SE
Aapplication
design
with
MVC.
<http://www.oracle.com/technetwork/articles/javase/mvc-136693.html>.
Disponível em
Acesso
em
05/05/2011.
GOODRICH, Michael T; TOMASIA, Roberto. Projeto de algoritmos: fundamentos, análise
e exemplos de internet. Tradução: Bernardo Copstein e João Batista Oliveira. Porto Alegre:
Bookman, 2004.
JFREECHART.
JFreeChart.
Disponível
em
<http://www.jfree.org/jfreechart/index.html>.
Acesso em 10/06/2011.
JSYNTAXPANE.
Jsyntaxpane:
project
home.
Disponível
em
<
http://code.google.com/p/jsyntaxpane/>. Acesso em 10/06/2011.
LUCENA, Marisa. Diretrizes para a capacitação do professor na área de tecnologia
educacional: critérios para a avaliação de software educacional. Disponível em <
http://www.inf.pucrs.br/~marciabc/20072/infoesp/apoio/formacaoprofs_avaliacaoSW.pdf
>.
Acesso em 09/03/2011.
MCCLUSKEY,
Glen.
Using
java
reflection.
Disponível
em
<http://java.sun.com/developer/technicalArticles/ALT/Reflection>. Acesso em 18/04/2011.
NETBEANS.
Download
NetBeans
IDE
6.9.1.
http://netbeans.org/downloads/6.9.1/>. Acesso em 10/06/2011.
Disponível
em
<
65
ORACLE.
Annotations.
Disponível
em
<http://download.oracle.com/javase/1.5.0/docs/guide/language/annotations.html>.
Acesso
em
27/04/2011.
ORACLE.
Enum
ElementType.
Disponível
em
<
http://download.oracle.com/javase/1,5.0/docs/api/java/lang/annotation/ElementType.html>.
Acesso em 29/05/2011.
ORACLE.
Enum
RetentionPolicy.
Disponível
em
<http://download.oracle.com/javase/1,5.0/docs/api/java/lang/annotation/RetentionPolicy.html
>. Acesso em 29/05/2011.
ORACLE.
Inteface
JavaCompiler.
Disponível
http://download.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html>.
em
<
Acesso
em
29/05/2011.
PDFHELP. PDFhelp: superior JavaHelp replacement for all Java developers. Disponível em
< http://www.pdfhelp.org/index.php>. Acesso em 10/06/2011.
PRESSMAN, Roger S. Engenharia de software. 6. ed. São Paulo: McGraw-Hill, 2006.
SANTANCHÉ, C.A.; TEIXEIRA, C. Integrando instrucionismo e construcionismo em
aplicações
educacionais
através
do
casa
mágica.
Salvador.
<http://www.nuppead.unifacs.br/artigos/IntegrandoInstrucionismo.pdf>.
Disponível
em
Acesso
em
09/03/2011.
SANTOS, R. P.; COSTA, H. A. X. TBC-AED e TBC-AED/WEB: Um Desafio no Ensino de
Algoritmos, Estruturas de Dados e Programação. In: IV Workshop em Educação em
Computação e Informática do Estado de Minas Gerais (WEIMIG’2005), Varginha/MG –
Brasil. CD dos Anais do IV Workshop em Educação em Computação e Informática do Estado
de Minas Gerais, 2005. v. 1.
SILVEIRA,
Tiago.
Classloaders.
Disponível
em
<http://www.guj.com.br/articles/124>.
Acesso em 28/04/2011.
SOMMERVILLE, Ian. Engenharia de Software. Tradução André Mauricio de Andrade
Ribeiro. São Paulo – SP; Pearson Addison Wesley – 2003.
66
TAYLOR,
Brandon
E.
Java
class
loading:
the
basics.
Disponível
em
<http://www.developer.com/java/other/article.php/10936_2248831_2/Java-Class-LoadingThe-Basics.htm>. Acesso em 28/04/2011.
TOSCANI, Laira Vieira; VELOSO, Paulo A. S. Complexidade de algoritmos. Porto Alegre:
Instituto de informática da UFRGS: Editora Sagra Luzzatto, 2005.
VALENTE, José A. Formação de profissionais na área de informática em educação.
Disponível
em:
http://www.iei.org.br/~vanderlei/anteriores/2007/tecnico/teorias_aprendizagem/valente.pdf
<
>
Acesso em 09/03/2011.
VALENTE, José A. Informática na Eeducação: Instrucionismo x Construcionismo.
Campinas: Núcleo de Informática Aplicada à Educação - Nied - Universidade Estadual de
Campinas, 1997. Manuscrito não publicado.
ZIVIANI, Nilvio. Projeto de algoritmos: com implementações em Pascal e C. 2. ed. rev. e
ampl. São Paulo: Pioneira Thomson Learning, 2004.
67
ANEXO A – ALGORITMO COMPLEMENTAR
Árvore Binária
i.
Código da aba de geração das entradas.
@TamanhoEntrada(tam={4,8,16,56,78,89,120,149})
int x;
#main
BinaryTree b = new BinaryTree();
b.gerarArvore(x);
b.pesquisar(b, 18);
ii. Código de contagem das operações.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
/**
*
* @author rodson
*/
class BinaryTree {
public BinaryTree noEsq = null;
public BinaryTree noDir = null;
public int dado = -1;
public int getRandomNumber(int inicio, int fim) {
Random random = new Random();
long range = (long) fim - (long) inicio + 1;
long fraction = (long) (range * random.nextDouble());
int randomNumber = (int) (fraction + inicio);
return randomNumber;
}
public void gerarArvore(int qtdNo){
ArrayList<Integer> arr = new ArrayList<Integer>();
for(int i=0; i<qtdNo; i++){
arr.add(i);
}
int k = arr.get(arr.size()/2);
inserir(this, k);
for(Integer i : arr){
if(i!=k){
inserir(this, i);
}
}
68
}
public void inserir(BinaryTree no, int dado) {
if (no.dado == -1) {
no.dado = dado;
} else {
if (no.dado > dado) {
if (no.noEsq == null) {
BinaryTree b = new BinaryTree();
b.dado = dado;
no.noEsq = b;
} else {
inserir(no.noEsq, dado);
}
} else if (no.dado < dado) {
if (no.noDir == null) {
BinaryTree b = new BinaryTree();
b.dado = dado;
no.noDir = b;
} else {
inserir(no.noDir, dado);
}
}
}
}
public void preOrdemAjudante(BinaryTree no) {
if (no == null) {
return;
}
preOrdemAjudante(no.noEsq);
preOrdemAjudante(no.noDir);
System.out.println(no.dado + "");
}
public boolean pesquisar(BinaryTree no, int key){
if(no == null){
//contando retorno
@contar();
return false;
}
else {
if(no.dado < key){
//contando retorno
@contar();
return pesquisar(no.noDir, key);
}
else{
if(no.dado > key){
//contando retorno
@contar();
return pesquisar(no.noEsq, key);
}
else{
//contando retorno
@contar();
return true;
}
69
}
}
}
}
Download