Você está na página 1de 24

Algoritmos e Estruturas de Dados

- Estrutura de Dados
- Uma estrutura de dados � um modo particular de armazenamento e
organiza��o dos dados que possibilite o uso
dos mesmos de forma eficiente.
- As estruturas de dados diferem umas das outras pela disposi��o ou
manipula��o de seus dados. A disposi��o
dos dados em uma estrutura obedece a condi��o preestabelecida e
caracteriza a estrutura.
- Nenhuma estrutura de dados �nica funciona bem para todas as
finalidades. Dessa forma, � importante conhecer
seus pontos fortes e suas limita��es. (Ex: se eu tenho a
necessidade de inserir elementos em ordem
eu preciso de uma estrutura de dados que comporte isso. Temos que
verificar qual estrutura de dados
utilizar em cada cen�rio)

- Algoritmos
- Um algoritmo � qualquer procedimento computacional bem definido que
toma algum valor ou conjunto de valores
como entrada e produz algum valor ou conjunto de valores como
sa�da. (Algoritmo � um processo
sistem�tico apra resolver um problema)
- Um algoritmo � uma sequencia de etapas computacionais que transformam
a entrada na sa�da.
ENTRADA -> PROCESSAMENTO -> SA�DA (Entrada � processada e ao
final deste � dada uma sa�da)

- Esses dois assuntos est�o interrelacionados visto que a escolha correta da


estrutura adequada a cada caso depende
diretamente do conhecimento de algoritmos que ir�o manipular essa
estrutura da maneira mais efici�nte.

- Representa��o de Algoritmos
- Fluxograma: Trata-se de uma representa��o esquem�tica de um processo
ou uma sequencia de passos, feito atrav�s
de gr�ficos que ilustram de forma descomplicada a transi��o de
informa��es entre os elementos que
o comp�e. Ele mostra o fluxo de um programa atrav�s de diagramas,
ex: INICIO -> L� um N�mero ->
Se > 5 -> Encerra. O Le um numero esta num ret�gulo que indica um
comando, a condi��o � um los�ngulo.
- Pseudoc�digo / Pseudolinguagem: O pseudoc�digo permite que o
programador possa se concentrar na l�gica e
nas estruturas de controle e n�o com as regras de uma linguagem
espec�fica. Ao contr�rio de uma
linguagem de programa��o n�o existe um formalismo r�gido de como
deve ser escrito o algoritmo.
O algoritmo deve ser f�cil de se interpretar e f�cil de
codificar, por�m, sem ambiguidades. (Inicialmente
esses pseudoc�digo eram apenas em ingl�s, mas com a sua
dissemina��o tb existe em portugu�s, o portugues
estruturado ou portugol.)

- TAD � Tipo Abstrato de Dados


- A abstra��o enfatiza apenas as caracter�sticas essenciais de um
objeto, levando em considera��o um cen�rio
espec�fico. (Ex: para um desfile de moda eu enfatizo algumas
caracter�sticas de uma pessoa como nome,
peso, altura, etc. J� num meio acad�mico eu enfatizo a s�rie da
pessoa, n�mero de cadeiras, etc.).
O conjunto de caracter�sticas resultante da abstra��o �
materializado na forma de um
TAD � Tipo Abstrato de Dados (onde se d� enfase apenas nas
caracter�sticas relevantes de um cen�rio
espec�fico).
- Um tipo abstrato de dados agrupa a estrutura de dados juntamente com
as opera��es que podem ser feitas
sobre esses dados.
TIPO ABSTRATO
----------------------
| Estrutura de Dados | Aqui temos os dados propriamente
ditos
----------------------
| Opera��es | Interface com o mundo (essas opera��es
v�o representar a interface desse
---------------------- tipo abstrato de dados. Assim, o
cliente s� se comunica com o TAD atrav�s
das opera��es.
- O TAD encapsula a estrutura de dados de forma que os usu�rios s�
tenham acesso a algumas opera��es
disponibilizadas sobre esses dados. (Os dados est�o protegidos,
encapsulados)
- Obs Exerc�cios: As pilhas podem ser declaradas como tipos abstratos
de dados.
A fila � um concceito, e eu posso representar qualquer conceito
como um tipo abstrato de dados.
Podemos utilizar tipos primitivos ou complexos para formar um
tipo de dados abstrato.
S�o tipos de dados que escondem a sua implementa��o de quem o
manipula; de maneira geral as opera��es
sobre estes dados s�o executadas sem que se saiba como isso �
feito. (N�s encapsulamos os dados, o
usu�rio n�o tem visibilidade da implementa��o das opera��es, ele
somente sabe utiliz�-la. Ele tb n�o
sabe como os dados est�o dispostos nessa estrutura, creio que
seja do tipo: a fila � implementada com
array ou ponteiros?).
A escolha de estruturas internas de dados utilizados por um
programa pode ser organizada a partir de
TADs que definem classes de objetos com caracter�sticas
SEMELHANTES, � como termos um classe PESSOA e
objetos do tipo PESSOA, todos ser�o semelhantes, o que muda � o
estado.

- Complexidade de algoritmos
- Principais caracter�sticas
- Para ser capaz de classificar um algoritmo como sendo bom, s�o
necess�rias formas de analisar o mesmo.
Analisar um algoritmo significa prever os recursos de que o
algoritmo necessita. (Esses recursos
podem ser mem�ria, largura de banda, processador, etc)
- Em geral, pela an�lise de v�rios algoritmos candidatos para um
problema, pode-se identificar o mais
eficiente. (Podemos ter mais de um candidato, mas sempre
descartamos os menos eficientes)
- O tempo de execu��o de um algoritmo pode ser determinado por:
- M�todos emp�ricos - obter o tempo de execu��o atrav�s da
execu��o propriamente dita do
algoritmo, considerando-se entradas diversas. (� a execu��o
do algoritmo, ou seja, implementar,
compilar e executar esse algoritmo. O problema � que temos
influ�ncias externas nessa
execu��o como a linguagem utilizada, compilador, sisop,
al�m de influencia de hardware.)
- M�todos anal�ticos - O objetivo dos m�todos anal�ticos �
determinar uma express�o matem�tica
que traduza o comportamento de tempo de um algoritmo. Esse
m�todo visa aferir o tempo de
execu��o de forma independente das condi��es locais de
processamento. (N�o executaremos o
algoritmo, a ideia � analisa-lo e chegar a uma expressao
que represente o seu comportamento).
- Nota��o Assint�tica
- Quando observamos tamanhos de entradas suficientemente grandes
para tornar relevante apenas a ordem
de crescimento do tempo de execu��o de um algoritmo,
estamos estudando a efici�ncia assint�tica.
(Estamos preocupados com o modo como o tempo de execu��o do
algoritmo aumento com a entrada no
limite, na que essa entrada aumenta sem limita��es).
- Em geral, um algoritmo que � assintoticamente mais eficiente
(menor complexidade que o outro, qto maior
a sua eficiencia menor a sua complexidade) ser� a melhor
escolha para todas as entradas, exceto
as muito pequenas. (Assim, essa analise vale para entradas
suficientemente grandes)
- A efici�ncia assint�tica observa apenas as entradas grandes o
suficiente para tornar relevante apenas
a ordem de crescimento do tempo de execu��o.
- N�o ser�o consideradas constantes aditivas ou multiplicativas
na express�o matem�tica obtida. (Isso
retira essas constantes para tornar mais simlificada a
express�o)
- Depois de simplificar a express�o, ficaremos apenas com a parte
da fun��o de maior complexidade.
- Por exemplo:
- Um valor de n�mero de passos igual a 3n ser� aproximado
para n. (retira a constante aditiva
ou multiplicativa, nesse caso a multiplicativa).
- Um valor de n�mero de passos igual n^2 + 2 ser�
aproximado para n^2. (fica apenas com a parte
de maior complexidade representando a ordem de
crescimento desse algoritmo).
- Nota��o O (�micron)
- A nota��o O (Big O Notation) � �til para descrever limites
superiores de complexidade. (Limites
superiores de complexidade refere-se ao tempo de execu��o
do algoritmo no sentido do seu pior
caso, assim, o limite superior � o pior caso de execu��o
daquele algoritmo para qualquer entrada).
- Defini��o: Sejam f e g fun��es positivas. Diz-se que f esta na
ordem O de g, escrevendo-se f = O(g),
quando existir uma constante c > 0 e um valor n
suficientemente grande, tal que: f(n) <= c.g(n)
(Ou seja, temos duas fun��es f e g, se f � da ordem O(g) o
g vai ser maior ou igual a f, mas sempre
considerando uma entrada muito grande).
- A fun��o g atua como um limite superior para valores
assint�ticos. (O g seria o pior caso, � o topo
do grafo)
- Exemplo:
# 5n^2 + 3nlogn + 2 � da ordem de O(n2) (desconsidera
constantes multiplicativas e aditivas. Assim
em 5*n^2 descarta o 5, em 3nlogn tira o 3 e o + 2
vira 1. Mas ficamos com o valor de
maior complexidade que � n^2).
5n^2 + 3nlogn + 2 � O(n3) (Essa afirmativa � correta
lembrando que f tem que ser <= g, nesse
caso o f vai dar n^2 e o g � n^3, assim f <= g essa
afirmativa � correta.)
- Obs: No slide 24 do EDA01 podemos verificar que no inicio do
gr�fico qdo a entrada ainda � pequena
tem-se f maior que g, mas depois com entradas maiores tem-
se que g fica maior que f.
- Obs 2: Cuidar com a confus�o, Ex de como isso pode ser cobrado
em exerc�cio:
Considere os seguintes algoritmos e suas complexidades na
nota��o Big O:
- Algoritmo A: O(log n)
- Algoritmo B: O(n2)
- Algoritmo C: O(n . log n)
Considerando-se o pior caso de execu��o destes algoritmos,
� correto afirmar que o algoritmo:
(A) A � o menos eficiente.
(B) C � o menos eficiente.
(C) A n�o � o mais eficiente nem o menos eficiente.
(D) B � o menos eficiente. (CORRETA)
(E) C � o mais eficiente.

Pode-se notar que ele s� quer que fa�amos uma poss�vel


simplifica��o e redu��o para verificar
qual � o pior caso, n�o tem nada de comparar fun��es.

- Obs 3: No desenvolvimento de um sistema de an�lise financeira,


um programador utilizou um algoritmo
cuja complexidade de tempo, no pior caso, � igual a O(n).
Outro programador aponta um algoritmo
de melhor complexidade igual a
(A) O(log n). (CORRETA)
(B) O(n log n).
(C) O(n2)
(D) O(2n)
(E) O(n!)

- Obs 4: Agora no caso abaixo temos que saber as caracter�sticas


das anota��es, � uma quest�o
diferente.

Se a complexidade de tempo de um algoritmo � da ordem de (n


log n), � correto afirmar que esse
algoritmo tamb�m �
(A) T (n).
(B) O(n2).
(C) O(n log n).
(D) O (log n).
(E) O (n).

Devemos lembrar que:


f = O(g) -> f(n) <= g(n) O define um limite
superior
f = T(g) -> f = O(g) e g = O(f) Devem ter mesmo
crescimento
f = O(g) -> f(n) >= g(n)
Assim, a fun��o que est� dentro dos parenteses deve ser
igual, maior ou igual ou ainda
menor ou igual a quem est� fora.

Tamb�m devemos lembrar a tabelinha 1, logn, n, nlogn, n^2,


n^3, a^n.

a) nlog n � igual a n? N�o!


b) nlog n � maior ou igual a n^2? N�o! Verificar que g �
quem est� dentro dos parenteses.
c) nlog n � maior ou igual a n log n? Sim!
d) nlog n � menor ou igual a log n? N�o!
e) nlog n � menor ou igual a n? N�o!

- Nota��o ? (theta)
- A nota��o ? � �til para exprimir limites superiores justos.
- Defini��o: Sejam f e g fun��es positivas. Diz-se que f � ?(g),
escrevendo-se f = ?(g), quando ambas
as condi��es f = O(g) e g = O(f) forem verificadas. A
nota��o ? exprime o fato de que duas
fun��es possuem a mesma ordem de grandeza assint�tica. (f e
g devem ser iguais)
- A nota��o ? permite dizer que duas fun��es crescem � mesma
taxa, at� fatores constantes.
- Exemplo:
5n^3 + 3n^2 + 2000 � ? (n3)

- Nota��o O (�mega)
- A nota��o O, descrita a seguir, � �til para descrever limites
inferiores assint�ticos.
- Defini��o: Sejam f e g fun��es positivas. Diz-se que f � O(g),
escrevendo-se f = O(g) quando existir
uma constante c > 0 e um valor n suficientemente grande,
tal que: f(n) >= c.g(n).
- A nota��o O fornece uma maneira assint�tica de dizer que uma
fun��o cresce a uma taxa que � "maior ou
igual" a de uma outra fun��o.
- Exemplo: 3nlogn + 2 � (n3) (Tira-se o multiplicativo 3 e o + 2
vira + 1. Assim, tem-se nlogn + 1.
Portanto, essa express�o est� errada, n^3 � maior que
nlogn, por isso est� errada.)
- Obs: No slide 26 do EDA01 podemos verificar que no inicio do
gr�fico qdo a entrada ainda � pequena
tem-se g maior que f, mas depois com entradas maiores tem-
se que f fica maior que g.

- Nota��o Assint�tica
- A complexidade de tempo de PIOR CASO corresponde ao n�mero de
passos que o algoritmo efetua no seu pior
caso de execu��o, isto �, para a entrada mais desfavor�vel.
A complexidade de pior caso fornece
um LIMITE SUPERIOR para o n�mero de passos que o algoritmo
pode efetuar, em qualquer caso.

- Fun��es mais usadas na an�lise de algoritmos


- Para saber a complexidade de um algoritmo, divide-se o mesmo em
classes de problemas, de acordo com o
par�metro que afeta o algoritmo de forma mais
significativa. (Como vimos temos uma express�o que
traduz o comportamento temporal do algoritmo e no caso da
an�lise assint�tica n�s vamos
simplificar e reduzir essa express�o a uma fun��o e essa
fun��o sim vai representar o
comportamento temporal desse algoritmo).

Aumento da complexidade
-----------------------------------------------> (+)
-----------------------------------------------------------
------------------
|CONSTANTE | LOGARITMO | LINEAR | NLOGN | QUADR�TICA |
C�BICA | EXPONENCIAL |
|1 | logn | n | nlogn | n^2 | n^3
| a^n |
-----------------------------------------------------------
------------------
(-) <-----------------------------------------------
Diminui��o da complexidade

- A fun��o constante
- Caracteriza algoritmos de complexidade 1,
independentemente do tamanho n de entradas. � o �nico
caso onde as instru��es dos algoritmos s�o executadas
num tamanho fixo de vezes.
(� a fun��o de menor nivel de complexidade, ex � um
algoritmo que identifica se
um numero � par ou impar. Ao entrar com um n�mero
verifica-se o resto para verificar
se � par ou impar. Sempre executa-se o mesmo conjunto
de instru��es.)
- A fun��o logaritmo
- Caracteriza algoritmos de complexidade logn. Ocorre
tipicamente em algoritmos que dividem
problemas em problemas menores. (Como exemplo o
algoritmo de busca bin�ria que tem
como objetivo buscar um elemento num vetor que deve
estar com os elementos ordenados.
Busca-se os elementos comparando-se com o elemento
central, se a entrada � maior
que o central descarta-se a parte inferior do vetor
pq o elemento n�o est� nela,
e isso faz-se recursivamente. O problema � dividido
em problemas menor e isso
caracteriza uma fun��o logaritmica.)
- A fun��o linear
- Caracteriza algoritmos de complexidade n. Uma opera��o
b�sica � executada em cada elemento
de entrada do algoritmo. (Ex: se temos dez elementos
na entrada executariamos 10
vezes no pior caso. Ex: pesquisa sequencial numa
lista que percorre-se da primeira
posi��o at� a �ltima posi��o do vetor no pior caso.)
- A fun��o nLogn
- S�o algoritmos de complexidade nLogn. Ocorre tipicamente
em algoritmos que dividem problemas
em problemas menores, por�m juntando posteriormente a
solu��o dos problemas menores.
(Ex: mergesort � um exemplo. Divis�o e conquista,
onde pega-se os elementos menores e
trabalha em cima deles).
- A fun��o quadr�tica
- S�o os algoritmos de complexidade n^2. Nesses algoritmos,
os itens s�o processados aos pares,
com la�os aninhados. (Ex: somat�rio de duas matrizes
que tem dois la�os aninhados
que identificam os elementos de cada matriz, e dentro
temos a soma dos elementos.
Tr�s la�os aninha � fun��o c�bica.)
- A fun��o c�bica
- S�o algoritmos de complexidade n^3. Nesses algoritmos, os
Itens s�o processados tr�s a tr�s,
com tr�s la�os aninhados. (Ex: multiplica��o de
matrizes com 3 loops)
- A fun��o exponencial
- S�o algoritmos de complexidade a^n. Por se tratar de
algoritmos muito custosos, possuem pouca
aplica��o pr�tica. (Ex: algoritmos de for�a bruta que
testam todas as possibilidades).
- Consideramos um algoritmo mais eficiente que outro se o tempo
de execu��o do seu pior caso apresenta
uma ordem de crescimento mais baixa. Quanto mais complexo,
menos eficiente.

- Arrays
- Principais caracter�sticas
- Um array � uma estrutura de dados que armazena um conjunto de
elementos de forma que os mesmos s�o
acessados por um �ndice.
- Os arrays podem ser unidimensionais (vetores) ou
multidimensionais (matrizes).
- Os arrays s�o agregados homog�neos, ou seja, todos os seus
elementos s�o de um mesmo tipo.
- Os vetores possuem tamanho fixo e suas posi��es s�o cont�guas
na mem�ria. (O compilador realiza
essa aloca��o contigua na mem�ria. Ele calcula a partir do
tamanho do vetor e do seu tipo
corrrespondente a qtdade necess�ria de mem�ria e ap�s esse
c�lcula ele aloca efetivamente).
- O �ndice inicial de um vetor � zero. Dessa forma, ao se
realizar uma varredura em um array, sempre
devemos considerar o intervalo de 0 ao tamanho do vetor
menos 1;
- Manipulando vetores
- Definindo vetores: int [] inteiros = new int [10];
- Acessando elementos em vetores: int terceiroElemento =
inteiros[2];
- Percorrendo todos os elementos de um vetor:
for (int indice = 0; indice < inteiros.length; indice++) {
int elemento = inteiros[indice];
//...
}
- Manipulando matrizes
- Definindo matrizes em java: int inteiros[][] = new int[5][5];
Linha com as suas respectivas colunas:
0[0,1,2,3,4] 1[0,1,2,3,4] 2[0,1,2,3,4] 3[0,1,2,3,4]
4[0,1,2,3,4]
- Acessando elementos em matrizes: int elemento = inteiros[2][3];
0 1 2 3 4
0
1
2 X
3
4
- Percorrendo todos os elementos de uma matriz
for (int linha = 0; linha < 5; linha++) {
for (int coluna = 0; coluna < 5; coluna++) {
int elemento = inteiros[linha][coluna];
//...
}
}
(Entra na primeira linha e percorre TODAS as suas colunas)
- Obs: Cuidar com a diferen�a entre vetores (unidimencionais) e
matrizes (multidimencionais) conforme
a quest�o: "Vetores s�o utilizados quando estruturas indexadas
necessitam de mais que um �ndice
para identificar um de seus elementos." Nesse caso est� errada
essa quest�o, ela est� tratando de
matrizes.
- Obs: Mais um exemplo entre vetores e matrizes:
� uma estrutura de dados dividida em linhas e colunas. Desta
forma, pode-se armazenar diversos valores
dentro dela. Para obter um valor � necess�rio identific�-lo por
meio do n�mero da linha e da coluna onde
est� armazenado. Trata-se de
(A) �rvore.
(B) matriz.
(C) pilha.
(D) fita.
(E) deque.

- Recursividade (Utilizado para implementar algoritmos sofisticados como os


de ordena��o. A recurs�o � uma forma de
dividirmos um problema em problemas menores que � resolvido a
cada recurs�o.)
- Principais caracter�sticas
- Um m�todo recursivo � aquele que possui uma ou mais chamadas
para si mesmo.
- Todo m�todo recursivo pode ser implementado de forma n�o
recursiva, tal que execute exatamente a mesma
computa��o. (De forma iterativa usando loops produzindo a
mesma sa�da)
- Frequentemente, os procedimentos recursivos s�o mais concisos
do que um n�o recursivo correspondente.
(S�o mais f�ceis de implementar para problemas dif�ceis do que os
n�o recursivos)
- Todo m�todo recursivo deve possuir um ou mais casos recursivos
e pelo menos um caso base. (Lembrando
que uma fun��o recursiva tem uma chamada para ela mesma no seu
corpo, isso � um caso recursivo. Um caso
base � uma situa��o trivial que n�o exige a recursao, seria o
ponto de parada da recurs�o)
- Um algoritmo n�o recursivo equivalente a um recursivo pode ser
mais eficiente.
- A depura��o de m�todos recursivos pode ser mais complexa.
- Durante o processamento do m�todo recursivo, os dados v�o para
uma �rea da mem�ria chamada stack (pilha).
(L� estao os dados dessa fun��o recursiva. Todos os dados gerados
durante a execu��o � armazenado na
pilha, l� est�o as informa��es de todas as recurs�es realizadas
at� a �ltima execu��o.)
- Exemplo de recurs�o
- O fatorial de um inteiro positivo n � definido como sendo o
produto dos inteiros de n at� 1. (Como
por exemplo o fatorial de 5! � 5*4*3*2*1. Mas fatorial de 0
� 1.)
- Por conven��o, o fatorial de 0 � 1 e o fatorial de 1 � 1.
- De maneira formal, para n>1 temos: n! = n x (n-1) x (n-2) ... x
2 x 1
- Implementa��o do fatorial de forma recursiva:
public int fatorialRecursivo(int numero) {
//caso base
if (numero == 0 || numero == 1) {
return 1;
} else {
//caso recursivo
return numero * fatorialRecursivo(numero - 1);
}
}

Como exemplo podemos testar um fatorial(5).


Primeiramente o progrma verifica se 5 � caso base (0 ou 1),
n�o! Ent�o ele cai no else
que chama return de 5 e chama ele mesmo de novo com 4 como
argumento (5-1). Antes de chamar a
fun��o recursiva a STACK MEMORY ter� os valores manipulados
nessa chamada sendo armazenados,
nesse caso armazena-se os valores da chamada 1, congela, e
agora chama a fun��o de novo que
� a segunda chamada. Faz-se novamente os passos acima como
testar o caso base, vai pro else
e assim por diante. Ser�o realizadas ao total 5 chamadas
at� chegarmos na quinta chamada que �
passado o 1 como argumento que ser� o caso base.
Agora os valores ser�o desempilhados retornando 2*1 que � a
mais interna e retorna o resultado
para a chama de cima que far� 3*2 e retorna 6 para a
pr�xima chamada, ap�s isso teremos
6*4 e retorna 24 para a pr�xima que faz 5*24 resultando em
120.
Essa pilha � limitada e pode ocorrer um estouro da pilha.

- Implementa��o do fatorial de forma n�o recursiva (aqui temos um


acumulador e n�o mais a pilha)
public int fatorialNaoRecursivo(int numero) {
int valorFactorial = 1;

for (int i=numero; i>0; i--) {


valorFactorial = valorFactorial * i;
}

return valorFactorial;
}

- Pesquisa em Vetores
- Pesquisa Sequencial
- Principais caracter�sticas
- M�todo de busca mais simples. Percorre o vetor
sequencialmente, desde o seu primeiro elemento,
at� que o valor seja encontrado ou que os elementos do
vetor se esgotem. (Dado um vetor e um
elemento procura-se este valor desde a primeira posi��o do
vetor at� encontra-lo.)
- A ideia b�sica do algoritmo seria folhear, por exemplo,
uma lista telef�nica p�gina a p�gina,
at� encontrar o nome desejado ou constatar que o mesmo n�o
existe. (N�o � muito eficiente)
- Algoritmo possui complexidade no pior caso O(n). (O pior
caso � qdo o elemento est� na �ltima
posi��o do vetor, dessa forma, ter�amos que percorrer e
fazer compara��es com todos elementos
do vetor. Outro caso � se o elemento n�o existe no vetor,
assim tb percorreriamos todo vetor)
- Implementa��o
public static int buscaLinear(int[] vetor, int
valorProcurado) {
for (int i=0; i<vetor.length; i++) {
if (vetor[i]==valorProcurado) {
return i;
}
}
return -1;
}

Como buscar o n�mero 40 nesse vetor?


|10|05|38|08|02|40|01|
Come�a no indice 0 que � 10, este valor n�o corresponde ao
valor procurado.
No segundo indice tb n�o, e assim at� chegar no �ndice 4
que � o 40.

- Pesquisa Bin�ria
- Principais caracter�sticas
- A ideia b�sica do algoritmo � percorrer o vetor como se
folheia, por exemplo, uma lista
telef�nica. Abandonando-se as partes do cat�logo onde o
nome procurado, com certeza, n�o ser�
encontrado. Assim, abrimos a metade do cat�logo e
verificamos o nome, se for maior descarta-se
o primeira meta e segue.
- Para a realiza��o desse tipo de busca, o vetor deve estar
ordenado.
- Esse m�todo exige acesso aleat�rio aos elementos do
conjunto.
- Algoritmo possui complexidade no pior caso O(logn).
(Inferior que o da busca sequencial, ent�o
� mais eficiente que a pesquisa sequencial. O pior caso �
qdo n�o � encontrado ou � o ultimo
elemento.)
- O pior caso ocorre quando o elemento procurado � o �ltimo
a ser verificado, ou mesmo n�o �
encontrado.
- Funcionamento do Algoritmo
- O vetor � dividido ao meio.
- � verificado se o valor procurado � igual ao valor que
corresponde � linha de divis�o. (Avalia
o elemento central primeiramente aqui)
- Caso elemento encontrado, fim da busca.
- Caso valor n�o seja o procurado, � verificado se esta
acima ou abaixo da linha de divis�o.
- Caso esteja abaixo, a parte superior � descartada,
caso contr�rio, a parte inferior �
descartada.
- Isso � feito sistematicamente at� que o valor seja
encontrado ou at� que seja identificado que
o valor n�o esta na lista. A cada compara��o metade dos
elementos da lista s�o descartados.
(Veja que estamos sempre cortando o array no meio e n�o
apenas uma �nica vez)
- Implementa��o iterativa
public int buscaBinaria(int[] array, int valorProcurado) {
int indiceEsq = 0;
int indiceDir = array.length - 1; //tamanho do menor
- 1, � o ultimo elem do vetor
int indiceMeio; //incide central do vetor

while (indiceEsq <= indiceDir) {


indiceMeio = (indiceEsq + indiceDir) / 2;
//corta o vetor ao meio

if (array[indiceMeio] < valorProcurado) {


//esta na parte superior do vetor
indiceEsq = indiceMeio + 1; //assim,
descarta a parte inferior e paga do
//meio em diante
} else if (array[indiceMeio] > valorProcurado)
{
indiceDir = indiceMeio - 1; //indice da
esq ainda aponta para o primeiro
//elemento e o da
direita agora n�o aponta
//mais para o �ltimo
e sim para a metade
} else {
return indiceMeio; //nesse caso � ele
mesmo
}
}
return -1;
}

Como buscar o n�mero 40 nesse vetor?


|01|02|05|08|10|38|40|

Primeiramente verifica-se que o vetor est� ordenado.


Temos que inicialmente: indiceEsq = 0, indiceDir = 6;
indiceMeio = 3; Na compara��o tem-se que
o valor 8 � menor que 40, assim indiceEsq =
indiceMeio + 1; Portanto, indiceEsq = 4.
Na pr�xima itera��o indiceMeio ser� 5, ap�s isso na
compara��o 38 � menor que 40 ent�o
indiceEsq = indiceMeio + 1; que d� 6. Ent�o indiceEsq
= 6 e indiceDir = 6.
Na pr�xima itera��o indiceMeio = (indiceEsq + indiceDir) /
2 que d� 6. Agora podemos ver que
40 n�o � menor que 40 e tb 40 n�o � maior que 40,
assim achamos o elemento.

- Implementa��o recursiva
private int buscaBinariaRecursiva(int[] array, int
indiceEsq, int indiceDir, int valorProcurado) {
int indiceMeio = (indiceDir + indiceEsq) / 2;

if (indiceEsq > indiceDir)


return -1;
else if (array[indiceMeio] == valorProcurado)
return indiceMeio;
else if (array[indiceMeio] < valorProcurado)
return buscaBinariaRecursiva(array, indiceMeio
+ 1, indiceDir, valorProcurado)
else
return buscaBinariaRecursiva(array, indiceEsq,
indiceMeio - 1, valorProcurado)
}
- Obs: Acerca de pesquisa de dados e de opera��es b�sicas sobre
estruturas, julgue os itens que se seguem.
A pesquisa sequencial � aplic�vel em estruturas n�o
ordenadas. (CORRETO)
- Obs 2: O algoritmo conhecido como busca bin�ria � um algoritmo
de desempenho �timo para encontrar a
posi��o de um item em:
(A) uma �rvore B.
(B) uma lista ligada ordenada.
(C) uma �rvore de busca bin�ria.
(D) um heap bin�rio.
(E) um vetor ordenado. (CORRETO)
Aten��o um desempenho �timo indica aquele que apresenta a
melhor performance entre todos aqueles
que procuram resolver o mesmo tipo de problema. Por isso
qdo temos um algoritmo que resolve da
melhor forma � considerado de desempenho �timo.
Uma lista ligada ordenada n�o poderia ser marcada pois ela
n�o permite acesso direto a um elemento,
temos que percorrer todos elementos para chegar num
determinado elemento.
- Obs 3: Julgue os itens a seguir, referentes a estrutura de
dados e organiza��o de arquivos.
Uma das formas mais simples e r�pida de busca em uma
estrutura de dados ordenada � o m�todo de
pesquisa bin�ria, que segue o paradigma de divis�o e
conquista. Se o item pesquisado estiver no
meio do vetor, a busca termina com sucesso. Caso contr�rio,
se o elemento do meio vier antes do
elemento buscado, ent�o a busca continua na metade
posterior e, se vier depois, a busca continua
na metade anterior do vetor. (CORRETO)
- Obs 4: Seja o seguinte vetor, ordenado de forma ascendente:
|10|20|30|40|50|60|70|80|90|
Caso se utilize um algoritmo de busca bin�ria, quantas
itera��es ser�o necess�rias para que o
valor 80 seja encontrado?
(A) 2
(B) 3 (CORRETA)
(C) 4
(D) 8
(E) 9
Primeiramente indiceEsq = 0, indiceDir = 8. Assim 8+0/2 = 4
que � o indiceMeio.
Depois tem-se indiceEsq = 5 e IndiceDir = 8 e assim 13/2 =
6 que corresponde ao valor 70 como
indiceMeio do pr�ximo vetor analisado. Como 70 n�o � ainda
o valor o 80 est� a direita, ent�o
na terceira itera��o temos 7+8/2 = 7 como indiceMeio que �
o 80. Fizemos 3 itera��es.
Se fosse a sequencial ter�amos 8 itera��es.

- Algoritmos de Ordena��o
- Principais caracter�sticas
- Os algoritmos de ordena��o s�o de fundamental import�ncia na
ci�ncia da computa��o.
- O melhor algoritmo para determinada aplica��o depende, entre
outros fatores, do n�mero de itens a
ordenar e do grau de ordena��o j� apresentado por esses
itens. (Alguns algoritmos s�o melhores
numa lista de elementos maiores do que outros que s�o
melhor para poucos elementos. Alguns
tb se beneficiam qdo alguns elementos j� est�o ordenados.)
- Ao se ordenar um conjunto de valores, uma quest�o relevante � o
tratamento de elementos que possuem o
mesmo valor. Um algoritmo de ordena��o � est�vel se n�o
altera a posi��o relativa de elementos
que t�m um mesmo valor. (Algumas listas de elementos podem
ter elementos repetidos. Outra
situa��o � n�o alterar a posi��o relativa.)
- Considerando um vetor desordenado com os elementos abaixo:
[44 , 55, 22(1), 66, 77, 33, 11, 22(2), 88] (O valor 22
aparece duas vezes)
- Quando o vetor � ordenado por um algoritmo est�vel, a ordem
relativa dos itens com chaves iguais
mant�m-se inalterada ap�s a ordena��o.
Vetor ordenado com algoritmo est�vel
[11, 22(1), 22(2), 33, 44, 55, 66, 77, 88]
(Ou seja, a ocorrencia do primeiro 22 encontrado ainda
encontr-se na frente da ocorr�ncia do
segundo 22 encontrado)
- Quando o vetor � ordenado por um algoritmo n�o est�vel, a ordem
relativa dos itens com chaves iguais �
alterada ap�s a ordena��o.
Vetor ordenado com algoritmo n�o est�vel
[11, 22(2), 22(1), 33, 44, 55, 66, 77, 88]
(Nesse caso, a segunda ocorr�ncia do 22 aparece na frente
da primeira ocorr�ncia do 22.)

- Selection Sort
- � um tipo de ordena��o por sele��o que consiste em trocar o
menor elemento de uma lista com o elemento
posicionado no inicio da lista, depois o segundo menor
elemento para a segunda posi��o e assim
sucessivamente. (Ou seja, seleciona inicialmente o menor
elemento da lista, esse elemento
vai ser trocado com o elemento da posi��o 0 do vetor, em
seguida vamos trabalhar com o elemento
do indice 1 selecionando o segundo menor elemento da lista
e trocando pelo indice 1 e assim
por diante...)
- Essa algoritmo admite uma varia��o onde a troca � baseada no
maior elemento que � posicionado no final
da lista. (Seria o processo inverso do anterior onde
seleciona o maior elemento que � trocado
com a ultima posi��o do vetor, depois o segundo maior que
troca com a penultima posi��o do
vetor e assim por diante...)
- Algoritmos de ordena��o n�o est�vel. (N�o mantem a ordem dos
elementos com chaves iguais)
- Complexidade O(n^2). (n^2 caracterizada por loop aninhados)
- Implementa��o do Selection Sort:
public void selectionSort(int [] valores) { //array de
inteiros
int menorValor; //armazena o indice com menor chave

for (int indice=0; indice<valores.length-1; indice++)


{ //percorre da posicao 0 at� a
//ultima
posicao do vetor
menorValor = indice; //de cara atribui o indice
corrente do loop ao menor valor

//loop interno indo do prox elemento do indice


em diante, assim verifica se tem
//algum elemento menor que o indice corrente
for (int j=indice+1; j<valores.length; j++) {
if (valores[menorValor]>valores[j]) {
menorValor = j;
}
}

//se menorValor � diferente do indice tem-se


que temos um valor menor.
if (menorValor != indice) {
int aux = valores[indice]; //guarda para
nao perder esse valor, visto
//que ele sera perdido
na proxima linha pq contera
//o menor elemento.
valores[indice] =
valores[menorValor]; //coloca no array que esta no loop
//mais
externo o menor valor
//encontrado
valores[menorValor] = aux; //Onde estava
o menor valor achado entra o
//que estava no indice
antes
}
}
}

Como ordenar o vetor abaixo com o Selection Sort?


|04|06|08|01|05|02|
Itera��o 1: Aponta-se para o indice 0 que tem o elemento 4.
O loop interno procura o menor valor
a partir da posi��o 1 em diante, n�o olha para tr�s.
Assim menorValor = 01 que est�
na posi��o 3. Assim com as trocas tem-se:
|01|06|08|04|05|02|
Itera��o 2: Nessa segunda itera��o do loop EXTERNO avalia-
se da posi��o 1, que est� o 6, em
diante. No loop interno compara-se 6 com 8, n�o �
menor, agora verifica-se que o 4
� menor, mas a pesquisa continua at� que 2 � menor
que 4, assim 2 � o menor valor.
|01|02|08|04|05|06|
E assim por diante..

- Bubble Sort
- O algoritmo de ordena��o bubble sort � um m�todo simples de
ordena��o por troca.
- O vetor � percorrido do inicio ao fim onde cada elemento
� comparado com o elemento posterior.
- Caso o elemento posterior seja menor, ocorre uma troca
entre os dois elementos.
- Esse procedimento garante que o maior elemento ficar� no
final do vetor.
(Compara o elemento da posi��o 1 com o da 2, se o da 1 �
maior faz a troca, depois compara
o elemento da posi��o 2 com o da 3, se maior faz a troca e
assim por diante.)
- Baixo desempenho para grandes quantidades de informa��es. (Bom
para poucas qtdades de informacoes)
- Na primeira itera��o s�o feitas n-1 compara��es, assim se temos
9 elementos faremos 8 comparacoes,
e o maior valor vai para o final do vetor. Na segunda
itera��o s�o feitas n-2 compara��es e o
segundo maior valor vai para o final do vetor, e assim por
diante. Isso ocorre por que a cada
itera��o o maior valor que ainda n�o foi para sua posi��o,
vai para o final do vetor.
- Algoritmos de ordena��o est�vel.
- Complexidade no pior caso: O(n^2).
- Implementa��o do Bubble Sort:
void bubbleSort(int valores[]) {
//a cada iteracao desse loop temos o maior valor no
fim do array
for (int i = valores.length - 1; i>0; i--) { //i
recebe o vetor todo, ele vai da ordem
//decrescente.
//esse loop coloca o maior no fim do array,
depois o i vai comprimir mais uma
//posicao e de novo temos o maior valor no
final.
for (int j=0; j<i; j++) { //vai de 0 at� o i-1
//compara o atual com o posterior
if (valores[j] > valores[j+1]) {
int aux = valores[j];
valores[j] = valores[j+1];
valores[j+1] = aux;
}
}
}
}

Como ordenar o vetor abaixo com o Bubble Sort?


|04|06|08|01|05|02|
Itera��o 1: j=indice 0 (elemento 4), i = indice 5;
Compara 4 com 6, nao � maior n�o tem troca, 6 com 8,
depois 8 com 1 sim
temos uma troca assim |04|06|01|08|05|02| depois com
5 e com 2 tb temos troca.
Assim, |04|06|01|05|02|08|
Itera��o 2: j = 0, mas i � indice 4 pois � decrementado no
loop externo.
Do i pra frente j� est� certo, por isso ele s�
trabalha o que vem antes do i.
E assim por diante...

- Ordena��o por Inser��o


- Os algoritmos inser��o direta e ordena��o shell s�o exemplos de
algoritmos de ordena��o por inser��o.
- Esse m�todo pode ser comparado com as a��es que realizamos ao
ordenar uma m�o de cartas de baralho.
As cartas s�o inseridas, uma de cada vez, em seu local
correto. Cada carta � inserida de forma
a manter a ordem por naipe e valor.
- Inser��o Direta:
- Comportamento:
- O vetor � dividido em dois subgrupos: um com os
elementos ordenados e outro com os n�o
ordenados.
- A princ�pio, o subgrupo ordenado tem somente o
primeiro elemento do vetor e o segundo
subgrupo todos os outros. (Ou seja, o primeiro
elemento j� est� ordenado e todos
os outros ainda n�o est�o)
- Cada elemento do subgrupo desordenado do vetor �
colocado no subgrupo ordenado do vetor,
um de cada vez, na posi��o correta. (Pega o
primeiro elemento do subgrupo
e coloca na posi��o correta, pega o pr�ximo e
ordenada e assim por diante)
- Ao final desse processo, todos os elementos do
vetor estar�o ordenados.
- Algoritmos de ordena��o est�vel.
- O algoritmo de inser��o direta � mais eficiente se os
elementos a serem ordenados j� estiverem
pr�ximos de sua ordem final de classifica��o.
(Diferente dos outros algoritmos a insercao
direta vai se beneficiar se os elementos j� estiverem
parcialmente ordenados. Ele ter�
um desempenho melhor nesse caso).
- Suas complexidade no pior caso � O(n^2). Ela ocorre
quando o vetor esta totalmente desordenado.
(temos dois loops aninhados. O pior caso � o vetor
totalmente desordenado)
- Sua complexidade no melhor caso � O(n). Ela ocorre quando
o vetor esta totalmente ordenado.
- Implementa��o da Inser��o Direta:
public void insertionSort(int[] valores) {
for(int i=1; i<valores.length; i++) {
//percorre todos elementos do vetor ainda
//n�o ordenados. O
i come�a em 1, vamos
//do segundo
elemento at� o �ltimo.
int temp = valores[i];
int j;

for (j=i-1; j>=0; j--) { //percorre os


ordenados e verifica onde o corrente
//do loop externo deve
ser inserido.
if (valores[j] < temp) { //se
temp(corrente) maior que valores de j
//que sao
elementos anteriores a ele qr
//dizer que temp
est� na posi��o correta.
break;
}
valores[j+1] = valores[j]; //vai
movimentando os valores para a
//direita e o
valor a ser colocado l� na
//frente est�
perdido, ele ser� retomado
//na comando
depois desse for, logo abaixo
}
valores[j+1] = temp; //coloca o i na
posi��o dele
//se for na primeira posi��o
do array o j ser� -1, e
//com j+1 temos j=0 que � a
primeira posi��o.
}
}

Como ordenar o vetor abaixo com a Inser��o Direta?


|04|06|08|01|05|02|
|04| � a parte ordenada, o resto � a parte
desordenada.

Primeira Itera��o (loop externo): i = 6; j = 4; 6>4?


Sim, ent�o est� na posicao correta.
Realizamos apenas uma compara��o nessa itera��o
e deu um break;
Segunda Itera��o: i = 8; j = 6; 8>6? Sim, ent�o est�
na posicao correta.
Realizamos apenas uma compara��o nessa itera��o
e deu um break;
Terceira Itera��o: i = 1; j = 8; 1>8? N�o, agora faz
outra compara��o 1>6 N�o tb,
ent�o mais uma compra��o 1>4 N�o, ent�o coloca
o 1 l� na frente. Veja que antes
fizemos apenas uma compara��o pq se o n�mero j�
� maior, quer dizer que os
anteriores a ele no ordenado tb s�o, n�o
necessitando fazer todas as compara��es.
Ele faz todas essas compara��es pq o for (j=i-
1; j>=0; j--) vai decrementando
at� chegar ao inicio dessa parte do vetor. O
valores[j+1] = valores[j]; vai
efetuando a troca.

- Heap Sort
- Esse algoritmo de ordena��o faz uso de uma estrutura de dados
chamada heap para gerenciar as
informa��es. (Usa o heap para ordenar os elementos)
- A estrutura de dados heap pode ser vista como uma �rvore
bin�ria quase completa. (numa �rvore bin�ria
cada n� pode ter at� no m�ximo dois filhos e no m�nimo zero
filhos)
- Existem dois tipos de heaps (heap de minimo e heap de m�ximo),
o algoritmo de ordena��o por heap
utiliza heaps de m�ximo. Nesse tipo de heap, o valor de um
n� deve ser no m�ximo o valor do
seu pai. (N�o podemos ter um n� com valor superior ao seu
pai)
- Heap sort � um algoritmo de ordena��o n�o est�vel. (chaves
iguais tem a ordem alterada apos a ordenacao)
- Possui complexidade O(nlogn).
- Opera��es de um heap:
- Max-Heapify � essa opera��o � usada para manter a
propriedade de um heap de m�ximo (essa
propriedade � aquele que um n� pode ser no m�ximo o
valor do seu pai). Ela possui
como entrada o arranjo A e o �ndice i para o arranjo.
Essa opera��o permite que A[i]
obede�a � propriedade do heap de m�ximo. (Garantimos
que passando determinado elemento
do array vamos garantir que ele mantenha um heap
integro com a propriedade de heap max.)
Ex de um heap:
16
14 10
08 07
- Build-Max-Heap � essa opera��o converte um arranjo em um
heap de m�ximo. (usa o Max-Heapify. Mas
o que ela faz � construir de fato o heap. � como
passar um array e ela constr�i um heap
integro)
- Representa��o de um heap de m�ximo:
16
14 10
8 7 9 3
2 4 1

|16|14|10|08|07|09|03|02|04|01|

N� Ra�z n�o tem pai, nesse caso � o 16, e sempre est� no


�ndice 0 do array.
O n� ra�z tem os filhos 14 e 10.
N�vel do n� � a quantidade de n�s da ra�z at� este n�. O
n�vel do n� ra�z � 0 e do
seus filhos � 1, e assim sucessivamente.
Em um heap de m�ximo o ra�z sempre cont�m o maior valor.
O array mapeia a �rvore a partir dos seus n�veis. Primeiro
mapeamos o n�vel 0 no array,
depois vem o n�vel 1 (14 e 10), depois o n�vel 2 (7,8,9,3)
e assim por diante sempre da
esquerda para a direita.
- Funcionamento do Heap Sort
- Constru��o de um heap de m�ximo no arranjo de entrada
(Build-Max-Heap operacao que
recebe o vetor e cria um heap de m�ximo).
- A sequencia abaixo � executada at� que n�o reste mais
nenhum elemento no heap:
- Coloca-se o A[0] (maior elemento) em sua posi��o
correta no vetor, efetuando uma troca
entre os elementos.
- O elemento de maior valor � excluido logicamente do
heap.
- Faz com que o elemento A[0] mantenha a propriedade
de um heap m�ximo (Max-Heapify vai
garantir que esse elemento esteja de acordo com
a propriedade de heap de m�ximo).
- Implementa��o do Heap Sort em java:
public void heapSort(int[] valores) {
buildMaxHeap(valores); //cria o heap a partir
dos valores do array
int comprimento = valores.length;

for (int i = valores.length - 1; i>0; i--)


{ //percorre do ultimo elemento do
//vetor at� o seu
segundo elemento.
swap(valores,i,0); //troca o ultimo
elemento do vetor com o da pos 0 pq
//no buildMax construimos um
heap de maximo em que na
//pos 0 temos o maior
elemento desse vetor. Mas ele
//troca deixando assim
descaracterizado o heap, onde a
//raiz foi para a ultima
posi��o, mas isso � corrigido
//na funcao abaixo
maxHeapify(valores,0,--comprimento);
//reordena passando a posi��o 0
//e descarta o ultimo
elemento do vetor q
//j� esta ordenado, por
isso diminui o compr.
}
}

Como ordenar o vetor abaixo com o Heap Sort?


|10|07|14|16|02|08|04|01|03|09|
Primeiramente chamamos o buildMaxHeap(valores); que
constr�i o heap de m�ximo abaixo:
16
14 10
8 7 9 3
2 4 1

|16|14|10|08|07|09|03|02|04|01|

Agora entramos no loop em que percorremos do fim do


array at� a segunda posicao e:
- Troca dos elementos (pega o elemento da
�ltima posi��o que � o 1 e troca
com o ra�z que � o 16)
- Exclui o elemento de maior valor do heap;
(assim o 16 est� excluido do heap.)
- Chama maxHeapify passando o elemento da
posicao 0 que � o 1 e o ultimo elemento
onde ser� retomado as propriedades de um
heap lembrando as propriedades
em que deve-se ter no m�ximo dois filhos
etc, assim o array agora ficara
|14|08|10|04|07|09|03|02|01|->|16| -> o
16 n�o � mais associado ao heap
- De novo trocamos o raiz com o �ltimo: |01|08|
10|04|07|09|03|02|14| pq
queremos o maior elemento pra ultima
posi��o do vetor. O 14 tb �
removido da heap, temos a heap: |01|08|
10|04|07|09|03|02|->|14|16|
Podemos verificar que os elementos fora
do heap est�o ficando em ordem.

Chamamos o maxHeapify(valores,0,--
comprimento); e ficamos com
|10|08|09|04|07|01|03|02| -> Esta nova
disposi��o do array � pq agora
temos um novo elemento raiz que
ter� novos filhos que ter�o seus
filhos, por isso muda-se a
disposi��o desse array.
- De novo troca: |02|08|09|04|07|01|03|10|
Chamamos Maxheapify e obtemos: |09|08|03|
04|07|01|02|->|10||14|16|
- De novo troca e o 9 sai do heap; |02|08|03|
04|07|01|09|->|10||14|16|
Chamamos Maxheapify e obtemos: |08|07|03|
04|02|01|->|09|10||14|16|

No fim teremos o vetor ordenado: |01|02|03|04|


07|08|09|10|14|16|

- Merge Sort (Ver outro material, ficou muito confuso a aula 11)
- Esse algoritmo segue o paradigma divis�o e conquista.
- Funcionamento do merge sort:
- Divis�o: Divide a sequ�ncia de n elementos que deve ser
ordenada em subsequ�ncias de n/2
elementos cada uma.
- Conquista: Ordena as duas sequencias recursivamente. A
recurs�o termina quando a sequ�ncia a
ser ordenada tiver apenas um elemento. (Resolve cada
parte dividida com recursao)
- Combina��o: Intercala as duas subsequ�ncias ordenadas
para produzir a resposta ordenada.
- A opera��o mais importante desse algoritmo � conhecida como
merge. Ela consiste da intercala��o de
duas sequencias j� ordenadas. (Merge � feita na combina��o
e trabalha nas duas seq. ja ordenadas)
- A opera��o merge recebe duas subsequ�ncias j� ordenadas e
mescla todos os valores mantendo o resultado
ordenado em um �nico subarranjo.
- Merge sort � um algoritmo de ordena��o est�vel.
- Possui complexidade O(nlogn).
- Implementa��o do Merge Sort em java:
Inicio e fim delimitam a faixa que ser� trabalhada por esse
m�todo
private void mergesort(int[] valores, int inicio, int fim)
{
if (inicio < fim) { //caso base qdo tivermos um unico
elemento
int meio = (inicio + fim) / 2; //divide o
problema em dois
mergesort(valores, inicio, meio); //ordena a
primeira metade do vetor
mergesort(valores, meio+1, fim); //ordena a
segunda metade
merge(valores,inicio,meio,fim); //mescla
}
}

//Mescla as duas sequencias recebidas. Vejams=os que nos


parametros temos o array e do
//inicio ao meio temos uma metade do vetor, e do meio + 1
at� fim temos a outra metade
private merge(int[] valores, int inicio, int meio, int fim)
{
int[] vetorTemp = new int[valores.length];

//copia TODOS os elementos no vetor temporario


for (int i = inicio; i<=fim; i++) {
vetorTemp[i] = valores[i];
}

//percorre os dois vetores l�gicos e vai copiando o


menor dos valores
int i = inicio;
int j = meio + 1;
int k = inicio;
while (i<=meio && j<=fim) {
if (vetorTemp[i] <= vetorTemp[j]) {
valores[k] = vetorTemp[i];
i++;
} else {
valores[k] = vetorTemp[j];
j++;
}
k++;
}
//Copia o restante dos elementos do vetor l�gico que
ainda possui elementos
while (i<=meio) {
valores[k] = vetorTemp[i];
k++;
i++;
}
}

- Implementa��o do Merge Sort em java:


|10|07|14|16|02|08|04|01|

O vetor tem 8 elementos; inicio=0, fim=7;


O elemento central � inicio+fim/2= 3.
Assim chama o mergesort(valores, 0, 3) e temos o array |10|07|14|
16|
Com a chamada recursiva tem-se de novo a compara��o (inicio �
menor que fim, Sim! POIS 0<3)
Calcula o centro de novo 0+3/2 = 1.
Assim chama o mergesort(valores, 0, 1) e temos o array |10|07|
Com a chamada recursiva tem-se de novo a compara��o (inicio �
menor que fim, Sim! POIS 0<1)
Calcula o centro de novo 0+1/2 = 0.
Assim chama o mergesort(valores, 0, 0) e temos o array |10|
Com a chamada recursiva tem-se de novo a compara��o (inicio �
menor que fim, N�O! POIS 0=0)
Chegamos no caso base. Execu��o desse m�todo acaba aqui!

Agora vamos voltar na pilha e cairemos na pr�xima chamada


recursiva tratando do meio+1 at� fim
O elemento central � 1 e o indice final tb � 1 pois temos um
vetor com apenas um elemento, acho que
faltou uma declara��o que fim = tamanho do vetor.
Assim chama o mergesort(valores, 1, 1) e CAI DE NOVO NO CASO
BASE!
Como encerrou-se as duas chamadas recursivas ser� executado o
merge().
O merge recebe dois vetores de entrada 10 e 7 e ordena eles;
Depois ainda desempilhando...

- Quick Sort
- O quick sort � um m�todo de ordena��o por troca que aplica o
paradigma de divis�o e conquista.
- Funcionamento:
- Um elemento do arranjo inicialmente ser� escolhido como
piv�. (N�o h� um concenso de como ele
deve ser escolhido. Aqui adotou-se que o ultimo
elemento do vetor ser� o pivo)
- Em seguida o arranjo � dividido em 2 subarranjos:
- Elementos menores ou iguais ao piv�.
- Elementos maiores que o piv�
(O pivo � usado no particionamento, a parte mais
importante do algoritmo. Elementos
menores para esquerda e maiores para direita)
- Os dois arranjos do passo anterior s�o ordenados
recursivamente com o quick sort.
- Observa��o: Caso base ocorre quando o vetor possui
somente um elemento.
- Esse algoritmo n�o requer uma estrutura complementar para sua
execu��o, todo o processamento ocorre no
mesmo arranjo de origem. (mergesort precisa de uma
estrutura complementar)
- Algoritmo de ordena��o n�o est�vel.
- Complexidade no pior caso O(n^2).
- Complexidade no melhor caso O(nlogn).
- Implementa��o do Quick Sort em java:
private void quicksort(int[] valores, int i, int f) {
if (i<f) { //verifica se o indice inicial � menor que
o indice final
int q = partition(valores, i, f);
quicksort(valores, i, q-1); //chamada recursiva
para o elementos inferiores
quicksort(valores, 1+1, f);
}
}

//seleciona o pivo e coloca para esquerda os menor e os


maiores na direita.
private int partition(int[] valores, int i, int f) {
int pivo = valores[f]; //seleciona o ultimo elemento
do vetor
int baixo = i - 1; //posicao anterior � posicao
inicial
for (int alto; alto < f; alto++) {
if (valores[alto] <= pivo) { //indice alto
menor que o pivo
troca(valores, ++baixo, alto); //troca o
valor que esta no indice alto
//pelo proximo valor do
indice baixo, ou seja,
//coloca uma posicao
depois do ultimo elemento dos
//baixos
}
}
troca(valores, ++baixo, f);

return baixo; //distingue a faixa de valores dos dois


vetores
}

Como ordenar o vetor abaixo com o Quick Sort?


|05|03|07|01|09|02|08|04|

pivo = 4;
Ap�s a execu��o do particionamento tem-se:
|03|01|02|04|09|07|08|05| - antes do 4 os menores, depois
os maiores

Agora ser� chamado recursivamente o m�todo quicksort para


cada um dos subvetores |03|01|02|
e novamente quicksort para |09|07|08|05|

O quatro j� est� na sua posi��o final de ordena��o, n�o


precisa mexer neles.

Primeiramente na chamada recursiva para |03|01|02| tem-se a


sele��o do pivo que � 2 e uma
chamada para o partition. Tem-se assim |01|02|03|

Agora executa-se o quicksort para segunda metade do vetor.


Tem-se |07|08|09|

- Tabela Resumo (Em ordem de efici�ncia. Os pior caso tem tudo n^2
menos o mais eficiente dos piores que � a
inser��o direta. J� os mais eficientes tem uma
exce��o que � o pior dos mais eficientes
que possui n^2.)

Algoritmo de Ordena��o Melhor Caso Caso M�dio Pior Caso


Ordena��o Est�vel
Selection Sort O(n^2) O(n^2)
O(n^2) N�o
Bubble Sort O(n^2) O(n^2) O(n^2)
Sim
Inser��o Direta O(n) O(n^2) O(n^2)
Sim
--- Acima os menos eficiente, abaixo os mais eficientes
HeapSort O(nlogn) O(nlogn) O(nlogn) N�o
Merge Sort O(nlogn) O(nlogn) O(nlogn) Sim
Quick Sort O(nlogn) O(nlogn) O(n^2)
N�o

Ordena��o por troca


# Bubble Sort
# Quick Sort
# Ordena��o por Inser��o
# Inser��o Direta
# Ordena��o por Sele��o
# Selection Sort
Heap Sort

Você também pode gostar