You are on page 1of 38

Universidade Federal de Ouro Preto

Instituto de Cincias Exatas e Biolgicas


Departamento de Computao

ALGORITMOS E ESTRUTURAS DE DADOS


Quinto Trabalho Prtico
Anlise de Desempenho de Algoritmos de Ordenao por
Comparao e suas Variaes e Otimizaes

Luiz Henrique Santos


Professor - David Menotti
Monitor - Kayran dos Santos
Monitor - Pedro Ismar Silva Souto

Ouro Preto
9 de dezembro de 2009

Sumrio
1 Introduo
1.1 Consideraes iniciais . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Computador usado para testes . . . . . . . . . . . . . . . . . . . . . .
1.3 Especificao do problema . . . . . . . . . . . . . . . . . . . . . . . .
2 Metodos de Ordenao
2.1 Ordenao Interna . . . . . . . . . . .
2.2 BubbleSort . . . . . . . . . . . . . . .
2.2.1 Implementao . . . . . . . . .
2.2.2 Comparao BubbleSort . . . .
2.3 SelectSort . . . . . . . . . . . . . . . .
2.3.1 Implementao . . . . . . . . .
2.3.2 Comparao SelectSort . . . . .
2.4 InsertSort . . . . . . . . . . . . . . . .
2.4.1 Implementao . . . . . . . . .
2.4.2 Comparao InsertSort . . . . .
2.5 Comparao dos Mtodos Simples . . .
2.6 QuickSort . . . . . . . . . . . . . . . .
2.6.1 Implementao . . . . . . . . .
2.7 HeapSort . . . . . . . . . . . . . . . . .
2.7.1 Implementao . . . . . . . . .
2.8 MergeSort . . . . . . . . . . . . . . . .
2.8.1 Implementao . . . . . . . . .
2.9 Comparao dos mtodos eficientes . .
2.10 Mtodos Simples x Mtodos Eficientes
3 Testes
3.1 Vetor
3.2 Vetor
3.3 Vetor
3.4 Vetor

Ordenado . . . . . . . .
Quase Ordenado . . . .
Aleatrio . . . . . . . .
Inversamente ordenado

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

1
1
1
1

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

3
4
5
6
7
8
8
10
11
11
15
15
16
17
19
21
22
22
24
25

.
.
.
.

26
26
28
30
32

4 Concluso

34

Lista de Figuras
1
2
3
4
5
6
7
8
9
10

Ilustrao do Algoritmo BubbleSort


Ilustrao do Algoritmo SelectSort
Ilustrao do Algoritmo InsertSort
Ilustrao do Algoritmo QuickSort
Ilustrao do Heap . . . . . . . . .
Ilustrao do mtodo HeapSort . .
Ilustrao do mtodo MergeSort . .
Grficos de atribuies . . . . . . .
Grficos de comparaes . . . . . .
Grficos de atribuies . . . . . . .

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

5
8
11
16
19
20
22
27
27
29

11
12
13
14
15

Grficos
Grficos
Grficos
Grficos
Grficos

de
de
de
de
de

comparaes
atribuies .
comparaes
atribuies .
comparaes

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

29
31
31
33
33

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

3
3
6
6
8
9
11
12
13
17
21
22

BubbleSort . . . . . . . . . . . . . . . . . . . . . . . . . .
BubbleSort Otimizado . . . . . . . . . . . . . . . . . . . .
SelectSort . . . . . . . . . . . . . . . . . . . . . . . . . . .
SelectSortOtimizado . . . . . . . . . . . . . . . . . . . . .
InsertSort . . . . . . . . . . . . . . . . . . . . . . . . . . .
InsertSort Sentinela . . . . . . . . . . . . . . . . . . . . . .
HeapSort Otimizado . . . . . . . . . . . . . . . . . . . . .
MergeSort Otimizado . . . . . . . . . . . . . . . . . . . . .
QuickSort Otimizado . . . . . . . . . . . . . . . . . . . . .
Eficientes x Simples . . . . . . . . . . . . . . . . . . . . . .
Atribuies para um vetor ordenado . . . . . . . . . . . . .
Comparaes para um vetor ordenado . . . . . . . . . . . .
Tempo de execuo para um vetor ordenado . . . . . . . .
Atribuies para um vetor quase ordenado . . . . . . . . .
Comparaes para um vetor quase ordenado . . . . . . . .
Tempo de execuo para um vetor quase ordenado . . . . .
Atribuies para um vetor aleatrio . . . . . . . . . . . . .
Comparaes para um vetor aleatrio . . . . . . . . . . . .
Tempo de execuo para um vetor aleatrio . . . . . . . .
Atribuies para um vetor inversamente ordenado . . . . .
Comparaes para um vetor inversamente ordenado . . . .
Tempo de execuo para um vetor inversamente ordenado

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

7
7
10
10
15
15
24
24
24
25
26
26
26
28
28
28
30
30
30
32
32
32

Lista de Programas
1
2
3
4
5
6
7
8
9
10
11
12

TItem . . . . . . . . .
TArray . . . . . . . . .
BubbleSort . . . . . .
BubbleSort Otimizado
SelectSort . . . . . . .
SelectSort Otimizado .
InsertSort . . . . . . .
InsertSortSentinela . .
InsertSortCursores . .
QuickSort . . . . . . .
HeapSort . . . . . . . .
MergeSort . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.

Lista de Tabelas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

Introduo

O objetivo deste trabalho analisar algoritmos de ordenao por comparao e


suas variaes e otimizaes

1.1

Consideraes iniciais

Ambiente de desenvolvimento do cdigo fonte: Microsoft Visual C++ 2008


Professional Edition.
Linguagem utilizada: Linguagem C.
Ambiente de desenvolvimento da documentao: TeXnicCenter 1 BETA 7.50Editor de LATEX.
Na anlise da ordem de complexidade dos algoritmos ser analisado o pior
caso sempre.
Foram passados ponteiros de estruturas para as funes para economizar memria.

1.2

Computador usado para testes

Processador Inter Core 2 Duo T6500 2.1 Ghz.


3Gb de Memria RAM .
Placa me compatvel com Dell Inspiron 1545
Windowns Vista Home Basic 32 bits

1.3

Especificao do problema

A anlise dos algoritmos ser dividida em duas partes. Na primeira, a anlise ser
sobre os algoritmos de ordenao simples (de ordem de complexidade O(2 ) - i.e.,
BubbleSort, SelectSort, InsertSort e algumas variaes). Voc dever implementar
os trs algoritmos citados e implementar variaes desses algoritmos de forma que
atravs de anlises de experimentos voc possa analisar:
Se vale a pena inserir a verificao de ordenao (houve troca) no algoritmo
BubbleSort;
Se vale a pena usar o algoritmo InsertSort com elemento sentinela;
Se vale a pena usar um algoritmo InsertSort tendo o arranjo implementado
atravs de apontadores/cursores;
Se vale a pena inserir uma verificao (Min == i) para evitar a troca, no
mtodo SelectSort.

A segunda parte ser sobre os algoritmos de ordenao por comparao ditos


eficientes, como MergeSort, HeapSort e QuickSort, que tem complexidade de tempo
de O( n log n ). So fornecidas implementaes convencionais e verses otimizadas.
Aproveite os algoritmos implementados por voc e verifique:
A entrada deve ser lida de um arquivo a ser fornecido como parmetro em linha
de comando ( int main(int argc, char**argv) ) composta de vrios conjuntos de
testes, onde cada linha do arquivo contm uma expresso aritmtica a ser avaliada,
no seguinte formato:
At que tamanho de entrada, vale a pena usar algoritmos O(2 ) com relao
a algoritmos O(n log n)
Como gerar os vetores

Considere vetores com a quantidade de elementos variando, i.e., 10, 100, 1.000,
10.000, 100.000, 1.000.000, etc. Considere tambm vetores sem valores repetidos.
Ainda, considere que todos os elementos dos vetores correspondem a valores inteiros
e para gerar os vetores inicias, utilize vetores ordenados, inversamente ordenados,
quase ordenados e aleatrios.
O que analisar

A anlise deve ser feita sobre o nmero de comparaes, atribuies e tempo


de execuo dos algoritmos. Procure organizar inteligentemente os dados coletados
em tabelas, e tambm construa grficos a partir dos dados. Ento, disserte sobre
os dados nas tabelas e grficos. Grande parte da avaliao ser realizada sobre a
anlise dos resultados, ou seja, sobre o que voc dissertar.
As implementaes dos algoritmos

Neste trabalho, est sendo disponibilizado (no site da disciplina) implementaes de algoritmos a serem utilizados para anlise da segunda parte do trabalho.
A compilao, interpretao e uso deste cdigo constitui parte da avaliao deste
trabalho prtico. A implementao dos outros algoritmos a serem utilizados na primeira parte, fica por sua conta. Voc dever entender o padro de programao do
cdigo fornecido e implementar os novos algoritmos seguindo esse padro.
Salienta-se que o uso desse programa pode ser realizado em linha de comando
(prompt), ou dentro do ambiente de programao que voc usa. Todavia, antes,
voc dever compilar o cdigo para gerar o arquivo executvel e configurar o arquivo
in.dat para realizar seus testes. Tambm est sendo fornecido um arquivo exemplo
de configurao , apenas ilustrativo , no o pegue/tome como referncia para seus
testes. O resultado da execuo do programa, ou seja os dados para voc analisar,
so gravados em log.txt.

Metodos de Ordenao

Ordenar corresponde ao processo de rearranjar um conjunto de objetos em ordem


ascendente ou descendente. O objetivo principal da ordenao facilitar a recuperao posterior de itens do conjunto ordenado. O objetivo principal da ordenao
facilitar a recuperao posterior de itens do conjunto ordenado. [2]
Geralmente os vetores so ordenados atravs de um campo nico entre eles chamado chave. Segue abaixo a estrutura criada para representar cada elemento do
vetor:
typedef struct
{
int key ; //Campo c ha v e
}TItem ;

Programa 1: TItem
Para testarmos cada algoritmo precisamos gerar vetores de diversos tamanhos
e de diversas forma como: ordenado, quase ordenado, aleatrio e inversamente ordenado. Foram usados as seguintes estruturas e funes para representar e gerar o
vetores para testes dos algoritmos:
#define SIZE 100

10

15

20

25

30

35

typedef struct
{
int pAnt ; // a n t e r i o r
int key ; //Campo c ha v e
int pProx ; // proximo
}TItem ;
typedef struct
{
TItem P o s i t i o n s ;
int p P r i m e i r o ;
int pUltimo ;
int S i z e ;
}TArray ;
// V e r i f i c a s e um v e t o r e s t a ordenado
int I s S o r t e d ( TArray ) ;
// Aloca um v e t o r
void A l l o c a t e ( TArray , int s i z e ) ;
// Gera um v e t o r de forma a l e a t r i a
void GenerateRandom ( TArray , int max) ;
// Gera um v e t o r de forma a l e a t r i a sem e l e m e n t o s r e p e t i d o s
void GenerateRandomNoRep ( TArray , int max) ;
// Gera um v e t o r de forma i n v e r s a m e n t e ordenado
void G e n e r a t e I n v e r t ( TArray , int max) ;
// Gera um v e t o r de forma q u a s e ordenada
void GenerateAlmostSorted ( TArray , int max) ;
// Gera um v e t o r de forma q u a s e ordenada sem e l e m e n t o s r e p e t i d o s
void GenerateAlmostSortedNoRep ( TArray , int max) ;
// Gera um v e t o r de forma ordenado
void G e n e r a t e S o r t e d ( TArray , int max) ;
// Copia um v e t o r
void Copy ( TArray , TArray , int , int , int , int ) ;
// Imprime um v e t o r

void P r i n t ( TArray ) ;
// L i b e r a a memria a l o c a d a par aumvetor
void FreeArray ( TArray ) ;

Programa 2: TArray

2.1

Ordenao Interna

Mtodos de ordenao interna so mtodos no qual consegue-se ordenar o arquivo


usando-se somente a memria pricipal do computador(memria RAM), ou seja, o
arquivo cabe todo na memria.
Um aspecto importante aspecto na escolha de um algoritmo de ordenao o
tempo gasto para ordenar o arquivo. Tambm podemos considerar o nmero de
comparaes entre as chaves e o nmero de movimentaes ou trocas dos itens do
arquivo.
Outro fator importante de extrema importncia a quantidade de memria
gasta para ordenar o arquivo. O uso econmico da memria disponvel muito
apreciado na ordenao interna. Mtodos que utilizam o prprio vetor para realizar
a ordenao, ou seja, no utilizam memria adicional so conhecidos como mtodos
in situ. [2]
Os mtodos de ordenao interna so classificados em dois grupos:
Mtodos Simples(2 ):
BubbleSort
SelectSort
InsertSort
Mtodos Eficientes( log ):
QuickSort
MergeSort
HeapSort
ShellSort

2.2

BubbleSort

o mtodo mais intuitivo e simples de ser implementado, porm o menos


eficiente. Os elementos vo borbulhando a cada iterao do mtodo at a posio
correta para ordenao da lista. A cada passada do algoritmo garante-se que o maior
elemento est na ultima posio do vetor. No recomenda para vetores com grande
quantidade de elementos pelo seu alto custo de comparaes e movimentaes. [1]

Figura 1: Ilustrao do Algoritmo BubbleSort

2.2.1

// B u b b l e S o r t
void BubbleSort ( TArray v , int nAt , int nComp)
{
int i , j ;
TItem aux ;
f o r ( i = 0 ; i < v>S i z e 1 ; i++ )
{
f o r ( j = 1 ; j < v>S i z e i ; j++ )
{
( nComp)++;
i f ( v>P o s i t i o n s [ j ] . key < v>P o s i t i o n s [ j 1 ] . key )
{
aux = v>P o s i t i o n s [ j ] ; ( nAt )++;
v>P o s i t i o n s [ j ] = v>P o s i t i o n s [ j 1 ] ; ( nAt )++;
v>P o s i t i o n s [ j 1] = aux ; ( nAt )++;
}
}
}

10

15

20

Implementao

Programa 3: BubbleSort
Esse algoritmo recebe como parmetros um vetor, uma varivel para contabilizar
as comparaes e outra para contabilizar as atribuies. Um loop de 0 at size - 1,
onde size o tamanho do vetor, e outro que vai de 1 at size -1 troca elementos 2
a 2 se o primeiro for maior que o segundo. A cada rodada do loop mais interno o
nmero de comparaes incrementado e a cada vez que entra no if o nmero de
atribuies incrementado 3 vezes.
Oura forma de se implementar o BubbleSort inserir uma verificao se houve
troca de itens no loop mais interno. Caso no haja trocas o vetor j est ordenado
e o algoritmo para. Essa modificao ser analisada na prxima seo e o cdigo
apresentado abaixo.

10

15

20

// BubbleSortO
void BubbleSortO ( TArray v , int nAt , int nComp )
{
int i , j , t r o c a ;
TItem aux ;
f o r ( i = 0 ; i < v>S i z e 1 ; i++ )
{
troca = 0;
f o r ( j = 1 ; j < v>S i z e i ; j++ )
{
( nComp)++;
i f ( v>P o s i t i o n s [ j ] . key < v>P o s i t i o n s [ j 1 ] . key )
{
aux = v>P o s i t i o n s [ j ] ; ( nAt )++;
v>P o s i t i o n s [ j ] = v>P o s i t i o n s [ j 1 ] ; ( nAt )++;
v>P o s i t i o n s [ j 1] = aux ; ( nAt )++;
troca = 1;
}
}
i f ( t r o c a == 0 )

break ;
}
}

Programa 4: BubbleSort Otimizado


Nesse algoritmo ele cria uma varivel para verificar se houve trocar no loop mais
interno. Caso no houver trocar o vetor j est ordenado e o algoritmo termina.
2.2.2

Comparao BubbleSort

Testamos o algoritmo BubbleSort comun e BubbleSort otimizado para vetores


de 10, 100, 1000, 10000 e 100000 elementos ordenados, quase ordenados, aleatrios
e inversamente ordenados e montamos as duas tabelas abaixo.
Tabela 1: BubbleSort
BubbleSort

Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente
Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente

At.
0
15
72
135
At.
0
18057150
68037096
149984142

10
Com.
45
45
45
45
10000
Com..
49995000
49995000
49995000
49995000

Tem.
0.000002
0.000003
0.000003
0.000003

At.
0
1179
7005
14847

Tem.
0.410720
0.551672
0.857445
1.062.986

At.
0
438474414
1767734192
2114940093

100
Com.
4950
4950
4950
4950
100000
Com.
704982704
704982704
704982704
704982704

Tem.
0.000041
0.000049
0.000085
0.000099

At.
0
171222
649560
1498500

1000
Com.
499500
499500
499500
499500

Tem.
0.003981
0.005170
0.008358
0.010063

Atri.
0
175656
664107
1498500

1000
Comp.
999
498510
498905
499500

Tem.
0.000009
0.004870
0.008100
0.010459

Tem.
50.547640
46.219327
85.148370
110.501586

Tabela 2: BubbleSort Otimizado


Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente
Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente

Atri.
0
3
39
135
Atri.
0
16936458
68328030
149984142

10
Comp.
9
17
45
45
10000
Comp.
9999
49985684
49978710
49995000

BubbleSort Otimizado
100
Tem.
Atri.
Comp.
0.000002
0
99
0.000002
1155
4209
0.000002
6714
4905
0.000003
14847
4950
30000
Tem.
Atri.
Comp.
0.000079
0
99999
0.549886
435576432
65833800
0.912763
1810376450
704930378
1.149.139
2114940093
704930378

Tem.
0.000003
0.000045
0.000081
0.000099
Tem.
0.000806
26.240775
81.658714
111.727621

Como pode ser observado nas duas tabelas cima, o BubbleSort com a otimizao
de verificao de troca mostrou-se muito melhor que o comum para um vetor ja
ordenado executando muito menos comparaes e executando muito mais rpido.
Para um vetor um vetor quase ordenado e aleatrio, o otimizado mostrou-se apenas
pouco melhor que o normal e para um vetor inversamente ordenado o BubbleSort
Otimizado mostrou-se igual ou um pouco pior que o comum visto que no so feitas
comparaes desnecessrias nessa disposio do vetor e so feitas uma atribuio 2
vezes e uma comparao de registros n vezes no Otimizado.

2.3

SelectSort

Seu princpio de funcionamento selecionar o menor elementos do vetor e trocalo com o item que est na primeira posio do vetor. Esse processo deve ser repetido
at que reste apenas um elemento no selecionado. Uma vantagem que ele executa
apenas uma troca por iterao. [2]

Figura 2: Ilustrao do Algoritmo SelectSort

2.3.1

// S e l e c t S o r t
void S e l e c t S o r t ( TArray v , int nAt , int nComp)
{
int i , j , Min ;
TItem aux ;
f o r ( i = 0 ; i < v>S i z e ; i ++)
{
Min = i ;
f o r ( j = i + 1 ; j < v>S i z e ; j ++)
{
( nComp)++;
i f ( v>P o s i t i o n s [ j ] . key < v>P o s i t i o n s [ Min ] . key )
Min = j ;
}
aux = v>P o s i t i o n s [ Min ] ; ( nAt )++;
v>P o s i t i o n s [ Min ] = v>P o s i t i o n s [ i ] ; ( nAt )++;
v>P o s i t i o n s [ i ] = aux ; ( nAt )++;
}

10

15

20

Implementao

Programa 5: SelectSort

Esse algoritmo percorre o vetor procurando a menor elemento, guarda a sua


posio e o troca com o primeiro elemento do vetor. Depois troca com o segundo
elemento e por assim em diante at que o vetor esteja ordenado.
Uma possvel otimizao para esse algoritmo seria no troca quando o menor
elemento for igual ao elemento a ser trocado. Essa modificao ser analisada na
prxima seo e o cdigo apresentado abaixo.

10

15

// S e l e c t S o r t O
void S e l e c t S o r t O ( TArray v , int nAt , int nComp)
{
int i , j , Min ;
TItem aux ;
f o r ( i = 0 ; i < v>S i z e 1 ; i ++)
{
Min = i ;
f o r ( j = i + 1 ; j < v>S i z e ; j ++)
{
( nComp)++;
i f ( v>P o s i t i o n s [ j ] . key < v>P o s i t i o n s [ Min ] . key )
{
Min = j ;
// aux=v>P o s i t i o n s [ Min ] ; ( nAt )++;
}
}
i f ( i != Min )
{
aux = v>P o s i t i o n s [ Min ] ; ( nAt )++;
v>P o s i t i o n s [ Min ] = v>P o s i t i o n s [ i ] ; ( nAt )++;
v>P o s i t i o n s [ i ] = aux ; ( nAt )++;
}

20

25

Programa 6: SelectSort Otimizado


Nesse algoritmo ele faz a troca se a posio Min for diferente da posio de
insero.

2.3.2

Comparao SelectSort

Testamos o algoritmo SelectSort comun e SelectSort Otimizado para vetores de


10, 100, 1000, 10000 e 100000 elementos ordenados, quase ordenados, aleatrios e
inversamente ordenados e montamos as duas tabelas abaixo.
Tabela 3: SelectSort
SelectSort

Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente
Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente

At.
30
30
30
30
At.
30000
30000
30000
30000

10
Com.
45
45
45
45
10000
Com..
49995000
49995000
49995000
49995000

Tem.
0.000003
0.000002
0.000002
0.000002

At.
300
300
300
300

Tem.
0.397812
0.406774
0.386035
0.401223

At.
300000
300000
300000
300000

100
Com.
4950
4950
4950
4950
100000
Com.
704982704
704982704
704982704
704982704

Tem.
0.000040
0.000040
0.000042
0.000071

At.
3000
3000
3000
3000

1000
Com.
499500
499500
499500
499500

Tem.
0.003917
0.003850
0.003681
0.003942

At.
0
300
2154
1500

1000
Com.
499500
499500
499500
499500

Tem.
0.004428
0.004086
0.004035
0.004115

Tem.
42.353865
41.728394
39.842798
44.026905

Tabela 4: SelectSortOtimizado
Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente
Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente

At.
0
3
18
15
At.
0
3000
21762
15858

10
Com.
45
45
45
45
10000
Com..
49995000
49995000
49995000
49995000

SelectSort Otimizado
100
Tem.
At.
Com.
0.000002
0
4950
0.000002
30
4950
0.000002
189
4950
0.000002
153
4950
100000
Tem.
At.
Com.
0.402462
0
704982704
0.404392
30000
704982704
0.393090
217539
704982704
0.420611
158019
704982704

Tem.
0.000038
0.000039
0.000042
0.000042
Tem.
41.517251
40.179751
40.197262
43.305694

Uma tima caracterstica do SelectSort encontrada nos testes executados que


o tempo de execuo varia muito pouco com a disposio do vetor de entrada. Isso
se deve ao fato do algoritmo sempre ter que percorrer o vetor todo para encontrar o
menor, ento a ordem dos elementos no importa. Pelos resultados obtidos nas duas
tabelas acima notou-se que o SelectSort otimizado executa muito menos atribuies
que o SelectSort comum em todos os casos. O nmero de comparaes igual nos
dois casos. Para vetores at 100 elementos o otimizado mostra-se pouco melhor que
o comum e para vetores acima de 100 elementos os dois so muito semelhantes.

10

2.4

InsertSort

Este o mtodo preferido do jogador de cartas. Em cada passo, a partir de i=2,


o i-simo item da sequncia apanhado e transferido para a sequncia no seu lugar
apropriado. [2]

Figura 3: Ilustrao do Algoritmo InsertSort

2.4.1

10

15

Implementao

// I n s e r t S o r t
void I n s e r t S o r t ( TArray v , int nAt , int nComp )
{
int i , j ;
TItem aux ;
f o r ( i = 1 ; i < v>S i z e ; i ++)
{
aux = v>P o s i t i o n s [ i ] ; ( nAt )++;
j = i 1;
while ( ( j >= 0 ) && ( aux . key < v>P o s i t i o n s [ j ] . key ) )
{
( nComp)++;
v>P o s i t i o n s [ j + 1 ] = v>P o s i t i o n s [ j ] ; ( nAt )++;
j ;
}
v>P o s i t i o n s [ j + 1 ] = aux ; ( nAt )++;
}
}

Programa 7: InsertSort

11

Esse algoritmo comea na segunda posio do vetor e seleciona uma carta a ser
inserido. Ele compara esta carta com as demais cartas sua esquerda j ordenadas
e acha a sua posio de insero. Assim que a carta inserida o vetor esta ordenado
e o algoritmo seleciona a prxima carta e repete esse processo at que seja a ltima
carta que j se encontra na posio correta.
Uma possvel otimizao deste algoritmo o uso de um elemento sentinela.
Essa modificao ser analisada na prxima seo e o cdigo apresentado abaixo.
void I n s e r t S o r t S e n t i n e l a ( TArray v , int nAt , int nComp ) // n i v i o
{
int i , j ;
TItem x , y ;
5

f o r ( i =1; i <v>S i z e ; i ++)


{
x=v>P o s i t i o n s [ i ] ; ( nAt )++;
j=i 1;
y=v>P o s i t i o n s [ 0 ] ; ( nAt )++;
( nComp)++;
i f ( y . key>x . key )
{
v>P o s i t i o n s [ 0 ] = x ; ( nAt )++;// s e n t i n e l a
x=y ; ( nAt )++;
}
while ( x . key < v>P o s i t i o n s [ j ] . key )
{
( nComp)++;
v>P o s i t i o n s [ j +1]=v>P o s i t i o n s [ j ] ; ( nAt )++;
j ;
}
v>P o s i t i o n s [ j +1]=x ; ( nAt )++;
}

10

15

20

25

Programa 8: InsertSortSentinela
Esse algoritmo usa o elemento sentinela para vigiar para que a posio de
insero do elemento no ultrapasse o comeo do vetor. Quando o algoritmo compara
o elemento com o sentinela sabe-se que o final do vetor e encontrou-se sua posio
de insero.

12

Outra possvel otimizao deste algoritmo o uso cursores.


void I n s e r t S o r t C u r s o r ( TArray v , int nAt , int nComp )
{
int i , k , tam ;
TItem aux ;
5

tam = v>S i z e ; // 2

10

15

20

25

//Arruma os c u r s o r e s do p r i m e i r o e l e m e n t o
v>P o s i t i o n s [ 0 ] . pAnt = 1;
v>P o s i t i o n s [ 0 ] . pProx = 1;
v>p P r i m e i r o = 0 ;
v>pUltimo = 0 ;
v>S i z e = 1 ;
// Ordenao
f o r ( k = 1 ; k < tam ; k++)
{
i = v>P o s i t i o n s [ v>p P r i m e i r o ] . pProx ;
( nComp)++;
// s e f o r o menor e l e m e n t o do v e t o r a t o momento
i f ( v>P o s i t i o n s [ v>S i z e ] . key < v>P o s i t i o n s [ v>p P r i m e i r o ] . key )
{
( nComp)++;
// A t u a l i z a s e os c u r s o r e s
v>P o s i t i o n s [ v>S i z e ] . pAnt = 1; ( nAt )++;
v>P o s i t i o n s [ v>S i z e ] . pProx = v>p P r i m e i r o ; ( nAt )++;
v>P o s i t i o n s [ v>p P r i m e i r o ] . pAnt = v>S i z e ; ( nAt )++;
// A t u a l i z a s e o p r i m e i r o
v>p P r i m e i r o = v>S i z e ; ( nAt )++;

30

35

}
// s e f o r o maior a t o momento
e l s e i f ( v>P o s i t i o n s [ i ] . key > v>P o s i t i o n s [ v>pUltimo ] . key )
{
// A t u a l i z a s e os c u r s o r e s
v>P o s i t i o n s [ v>S i z e ] . pAnt = v>pUltimo ; ( nAt )++;
v>P o s i t i o n s [ v>S i z e ] . pProx = 1;( nAt )++;
v>P o s i t i o n s [ v>pUltimo ] . pProx = v>S i z e ; ( nAt )++;
// A t u a l i z a s e o u l t i m o
v>pUltimo = v>S i z e ; ( nAt )++;

40

45

50

}
else
{
//Anda p e l o s c u r s o r e s a t achar a p o s i o de i n s e r o
while ( v>P o s i t i o n s [ v>S i z e ] . key > v>P o s i t i o n s [ i ] . key )
{
( nComp)++;
i = v>P o s i t i o n s [ i ] . pProx ;
}
// A t u a l i z a s e os c u r s o r e s
v>P o s i t i o n s [ v>S i z e ] . pAnt = v>P o s i t i o n s [ i ] . pAnt ; ( nAt )++;
v>P o s i t i o n s [ v>S i z e ] . pProx = i ; ( nAt )++;
v>P o s i t i o n s [ v>P o s i t i o n s [ i ] . pAnt ] . pProx = v>S i z e ; ( nAt )++;
v>P o s i t i o n s [ i ] . pAnt = v>S i z e ; ( nAt )++;

55

13

// A t u a l i z a s e o tamanho
v>S i z e ++;
}

60

Programa 9: InsertSortCursores
Para a implementao desse algoritmo foram adicionados algun campos pAnt,
pProx dentro de TItem e pPrimeiro e pUltimo dentro de TArray. Nessa implementao por cursores, no movimentamos itens nem chaves, as posies fsicas so fixas,
movimentamos apenas os cursores pAnt e pProx de cada Item.
Nesse tipo de implementao gasta-se mais memria para armazenar os cursores,
mas diminui o custo de arredar os itens do vetor para a insero em uma posio
do vetor.
A abordagem do algoritmo abstrair que o vetor esteja vazio e que vamos inserir
um elemento de cada vez. Como as posies so fixas, em cada insero apenas
movimentamos os cursores. O primeiro passo ajustar os cursores do primeiro
elemento e os apontadores pPrimeiro e pUltimo. Apartir dai vamos ajustando os
cursores de cada elemento do vetor um a um at o seu final juntamente com os
apontadores pPrimeiro e pUltimo.

14

2.4.2

Comparao InsertSort

Testamos o algoritmo InsertSort comun e InsertSort Sentinela para vetores de


10, 100, 1000, 10000 e 100000 elementos ordenados, quase ordenados, aleatrios e
inversamente ordenados e montamos as duas tabelas abaixo.
Tabela 5: InsertSort
InsertSort

Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente
Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente

At.
18
23
35
63
At.
19998
5771960
20090389
50014712

10
Com.
0
5
17
45
10000
Com..
0
5751962
20070391
49994714

Tem.
0.000002
0.000002
0.000002
0.000002

At.
198
786
2331
5147

Tem.
0.000136
0.062947
0.223080
0.536122

At.
199998
143452426
2027818515
705180029

100
Com.
0
588
2133
4949
100000
Com.
0
49994714
2027618517
704980031

Tem.
0.000003
0.000009
0.000108
0.000053

At.
1998
62624
197775
501498

1000
Com.
0
60626
195777
499500

Tem.
0.000016
0.000830
0.002078
0.005270

At.
2997
60317
210128
503496

1000
Com.
999
58315
208126
499500

Tem.
0.000019
0.000632
0.002143
0.004926

Tem.
0.001449
1.521.799
21.936880
55.268314

Tabela 6: InsertSort Sentinela


InsertSort Sentinela

Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente
Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente

At.
27
27
47
81
At.
29997
6118269
20259762
50034138

10
Com.
9
9
25
45
10000
Com..
9999
6098271
20239756
49994714

Tem.
0.000002
0.000002
0.000002
0.000002

At.
297
795
2278
5343

Tem.
0.000177
0.061608
0.210118
0.521029

At.
299997
144653579
2037977735
705374681

100
Com.
99
597
2076
4949
100000
Com.
99999
144453581
2037777727
704980031

Tem.
0.000003
0.000009
0.000022
0.000049
Tem.
0.001996
1.534368
21.352635
53.098769

Como pode ser observado nas duas tabelas cima, o InsertSort com Sentinela
mostrou-se ligeiramente pior que o InsertSort comum para todas as disposies dos
vetores e para todas as variveis avaliadas: atribuies, comparaes e tempo de
execuo. Portanto, no vale apena usar o InsertSort com Sentinela

2.5

Comparao dos Mtodos Simples

Nesta seo Analisaremos qual dos mtodos ditos simples (2 ) o mais eficiente
no que se refere ao nmero de atribuies, comparaes e tempo de execuo. Foi
selecionado a melhor implementao de cada mtodo para efeito de comparao:
BubbleSort Otimizado, SelectSort Otimizado e InsertSort
O mtodo SelectSort Otimizado o que apresenta o menor nmero de atribuies
dentre os 3 mtodos analisados.
O mtodo InsertSort o que apresenta o menor nmero de comparaes entre
chaves dentre os 3 mtodos analisados.
Quanto ao tempo de execuo, o SelectSort apresenta um tempo constante e razovel, O BubbleSort e InsertSort aumentam o tempo de execuo conforme o vetor
fica menos ordenado. Tomando a mdia dos tempos de execuo desses 3 mtodos,
nas 4 disposies possveis dos vetores, o mtodo InsertSort o que apresenta menor
tempo de execuo.
Para vetores j ordenados o BubbleSort Otimizado muito melhor que os outros
algoritmos: no realiza nenhuma atribuio e n - 1 comparaes apenas.

15

2.6

QuickSort

O QuickSort o algoritmo de ordenao interna mais rpido que se conhece


para uma ampla variedade de situaes, sendo provavelmente mais utilizado do que
qualquer outro algoritmo. Ele usa a estratgia de Dividir para conquistar. Essa
estratgia consiste em dividir o problema de ordenar itens em dois problemas menores, quando os problemas menores so resolvidos, o problema original tambm est
resolvido. [2]

Figura 4: Ilustrao do Algoritmo QuickSort

16

2.6.1

Implementao

Uma parte crucial do algoritmo a funo partio que tem que rearranjar o
vetor, dadas suas posies inicial e final, por meio da escolha de um elemento piv,
de tal forma que ao final os elementos menores que o piv esto a sua esquerda e os
elementos maiores esto a sua direita. [2]
// Q u i c k S o r t
void P a r t i t i o n ( int l e f t , int r i g h t , int i , int j , TArray pA , int NAt ,
int NComp)
{
TItem p i v o t , Aux ;
5

i= l e f t ; j=r i g h t ;

10

15

20

25

( NComp) +=4;
i f ( ( ( pA>P o s i t i o n s [ l e f t ] . key > pA>P o s i t i o n s [ r i g h t ] . key ) && (pA>
P o s i t i o n s [ l e f t ] . key < pA>P o s i t i o n s [ ( r i g h t+ l e f t ) / 2 ] . key ) ) | |
( ( pA>P o s i t i o n s [ l e f t ] . key < pA>P o s i t i o n s [ r i g h t ] . key ) && (pA>
P o s i t i o n s [ l e f t ] . key > pA>P o s i t i o n s [ ( r i g h t+ l e f t ) / 2 ] . key ) ) )
{
p i v o t = pA>P o s i t i o n s [ l e f t ] ; ( NAt)++;
}
else
{
( NComp) +=4;
i f ( ( ( pA>P o s i t i o n s [ l e f t ] . key < pA>P o s i t i o n s [ r i g h t ] . key ) && (pA>
P o s i t i o n s [ r i g h t ] . key < pA>P o s i t i o n s [ ( r i g h t+ l e f t ) / 2 ] . key ) ) | |
( ( pA>P o s i t i o n s [ l e f t ] . key > pA>P o s i t i o n s [ r i g h t ] . key ) && (pA>
P o s i t i o n s [ r i g h t ] . key > pA>P o s i t i o n s [ ( r i g h t+ l e f t ) / 2 ] . key ) ) )
{
p i v o t = pA>P o s i t i o n s [ r i g h t ] ; ( NAt)++;
}
else
{
p i v o t = pA>P o s i t i o n s [ ( r i g h t+ l e f t ) / 2 ] ; ( NAt)++;
}
}
do
{

30

35

40

45

while ( p i v o t . key>pA>P o s i t i o n s [ i ] . key )


{
( NComp)++;
( i )++;
}
while ( p i v o t . key<pA>P o s i t i o n s [ j ] . key )
{
( NComp)++;
( j );
}
i f ( i <=j )
{
Aux=pA>P o s i t i o n s [ i ] ; ( NAt)++;
pA>P o s i t i o n s [ i ]=pA>P o s i t i o n s [ j ] ; ( NAt)++;
pA>P o s i t i o n s [ j ]=Aux ; ( NAt)++;
( i )++;
( j );

17

}
} while ( i <=j ) ;
}
50

55

void S o r t ( int l e f t , int r i g h t , TArray pA , int NAt , int NComp)


{
int i , j ;
P a r t i t i o n ( l e f t , r i g h t , &i , &j , pA , NAt , NComp) ;
i f ( l e f t <j )
S o r t ( l e f t , j , pA , NAt , NComp) ;
i f ( i <r i g h t )
S o r t ( i , r i g h t , pA , NAt , NComp) ;
}

60

void QuickSort ( TArray pA , int NAt , int NComp)


{
S o r t ( 0 , pA>S i z e 1,pA , NAt , NComp) ;
}

Programa 10: QuickSort


A funo Partition recebe o vetor e suas posies final e inicial e faz a escolha
de um piv. Ele varre o vetor separando os elementos menores para a esquerda e os
maiores para a direita. Ela retorna os ndices da duas parties feitas e o nmero
de atribuies e comparaes.
A funo Sort recebe como parmetros o vetor, sua posio inicial, sua posio
final e chama a funo Partition para quebrar o vetor em 2. Essa funo chama
ela mesma duas vezes: uma para a primeira parte e outra para a segunda parte at
que reste apenas um elemento em cada parte. No final do algoritmo o vetor j esta
ordenado

18

2.7

HeapSort

O HeapSort um mtodo de ordenao cujo princpio de funcionamento utiliza


o mesmo princpio da ordenao por seleo. O custo para encontra o menor (ou
maior) elemento pode ser usado usando uma estrutura especial chamada filas de
prioridades.
Uma estrutura de dados eficiente para suportar essas operaes chamado heap.
O heap uma sequncia de itens tal que: para todo i = 1,2,...,n/2. Se temos um n
k, os ns 2k e 2k + 1 devem ser menores que k, ou seja, o n pai deve sempre ser
maior que os filhos. Uma desvantagem desse algoritmo o custo para construir o
heap. [2]

Figura 5: Ilustrao do Heap

19

Figura 6: Ilustrao do mtodo HeapSort

20

2.7.1

Implementao

O algoritmo HeapSort pode ser dividido em 3 funes: a constri heap, refaz


heap e o HeapSort.

10

15

20

// HeapSort
void RemakeHeap ( int l e f t , int r i g h t , TArray pA , int NAt , int NComp)
{
int i = l e f t , j ;
TItem aux ;
j = i 2 + 1;
aux = pA>P o s i t i o n s [ i ] ; ( NAt)++;
while ( j <= r i g h t )
{
if ( j < right )
{
( NComp)++;
i f (pA>P o s i t i o n s [ j ] . key < pA>P o s i t i o n s [ j + 1 ] . key )
j ++;
}
( NComp)++;
i f ( aux . key >= pA>P o s i t i o n s [ j ] . key )
break ;
pA>P o s i t i o n s [ i ] = pA>P o s i t i o n s [ j ] ; ( NAt)++;
i = j;
j = i 2 + 1 ;
}
pA>P o s i t i o n s [ i ] = aux ; ( NAt)++;
}

25

30

35

40

45

50

void MakeHeap ( TArray pA , int NAt , int NComp)


{
int l e f t ;
l e f t = pA>S i z e / 2 ;
while ( l e f t >= 0 )
{
RemakeHeap ( l e f t , pA>S i z e 1, pA , NAt , NComp) ;
l e f t ;
}
}
void HeapSort ( TArray pA , int NAt , int NComp)
{
int l e f t , r i g h t ;
TItem aux ;
MakeHeap (pA , NAt , NComp) ;
l e f t = 0 ; r i g h t = pA>S i z e 1;
while ( r i g h t >= 0 )
{
aux = pA>P o s i t i o n s [ 0 ] ; ( NAt)++;
pA>P o s i t i o n s [ 0 ] = pA>P o s i t i o n s [ r i g h t ] ; ( NAt)++;
pA>P o s i t i o n s [ r i g h t ] = aux ; ( NAt)++;
RemakeHeap ( l e f t , r i g h t , pA , NAt , NComp) ;
}
}

Programa 11: HeapSort

21

O primeiro procedimento construiu o heap com os elementos do vetor. Aps o


heap pronto retira-se o maior item do heap, que est no topo e chama-se a funo
refaz heap. Realiza-se essa operao at sobrar apenas um elemento.

2.8

MergeSort

O MergeSort outro algoritmo do tipo: Dividir para Conquistar. Sua idia


bsica criar uma sequncia ordenada a partir de duas outras tambm ordenadas.
Para isso, ele divide a sequncia original em pares de dados at que reste apenas
pares de elementos e ento ordena-os. Logo em seguida ele volta intercalando esses
grupos de elementos at montar todo o vetor novamente que vai sendo ordenado.
Uma desvantagem deste mtodo usar um vetor auxiliar, ou seja, tem complexidade
linear de espao.

Figura 7: Ilustrao do mtodo MergeSort

2.8.1

Implementao

O algoritmo MergeSort pode ser dividido em 3 funes: a constri heap, refaz


heap e o HeapSort.

10

15

// MergeSort
void Merge ( TArray pA , TArray pAux , int i n i t 1 , int end1 , int i n i t 2 , int
end2 , int NAt , int NComp)
{
int i , j , k ;
FreeArray ( pAux ) ;
A l l o c a t e ( pAux , end2i n i t 1 +1) ;
Copy (pA , pAux , i n i t 1 , end2 , NAt , NComp) ;
f o r ( i = 0 , j = end1i n i t 1 +1, k = i n i t 1 ; k <= end2 ; k++)
{
i f ( i == end1i n i t 1 +1 )
{
pA>P o s i t i o n s [ k ] = pAux>P o s i t i o n s [ j ++]; ( NAt)++;
continue ;
}
i f ( j == end2i n i t 2+end1i n i t 1 +2 )
{

22

pA>P o s i t i o n s [ k ] = pAux>P o s i t i o n s [ i ++];(NAt)++;


continue ;
}
( NComp)++;
i f ( pAux>P o s i t i o n s [ i ] . key < pAux>P o s i t i o n s [ j ] . key )
{
pA>P o s i t i o n s [ k ] = pAux>P o s i t i o n s [ i ++];(NAt)++;
}
else
{
pA>P o s i t i o n s [ k ] = pAux>P o s i t i o n s [ j ++];(NAt)++;
}

20

25

}
FreeArray ( pAux ) ;

30

35

void MSDivide ( TArray pA , TArray pAux , int i n i t , int end , int NAt , int
NComp)
{
int mid ;
i f ( end == i n i t )
return ;
mid = ( i n i t + end ) / 2 ;
MSDivide (pA , pAux , i n i t , mid ,NAt , NComp) ;
MSDivide (pA , pAux , mid+1, end , NAt , NComp) ;
Merge (pA , pAux , i n i t , mid , mid+1, end , NAt , NComp) ;

40

}
45

void MergeSort ( TArray pA , int NAt , int NComp)


{
TArray pAux ;
pAux = ( TArray ) m a l l o c ( s i z e o f ( TArray ) ) ;
A l l o c a t e ( pAux , pA>S i z e ) ;
MSDivide (pA , pAux , 0 , pA>S i z e 1,NAt , NComp) ;
FreeArray ( pAux ) ;

50

f r e e ( pAux ) ;
55

Programa 12: MergeSort


O MergeSort dividido basicamente em 2 partes: A Parte de Diviso do vetor
em partes iguais e a intercalao dos elementos dos vetores. O seu funcionamento
o seguinte: Calacula-se a posio do meio tendo como referncia a posio inicial e
final e chama-se a funo recursivamente para as duas partes. Depois das chamadas
recursivas chama-se a funo intercala pra juntar as duas partes ordenadas. A funo
intercala exige um vetor auxiliar para sua execuo.

23

2.9

Comparao dos mtodos eficientes

Nesta seo vamos comparar os algoritmos ditos eficientes( log ): MergeSort,


HeapSort e QuickSort em suas verses otimizadas. O cdigo desses algoritmos foram
disponibilizados pelo professor no site da disciplina. Testamos os algoritmos para
vetores de 10, 100, 1000, 10000 e 100000 elementos ordenados, quase ordenados,
aleatrios e inversamente ordenados e montamos as tabelas abaixo.
Tabela 7: HeapSort Otimizado
Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente
Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente

At.
83
84
81
74
At.
181460
180121
175801
166682

10
Com.
41
41
40
35
10000
Com..
244488
242597
237101
226720

HeapSort Otimizado
100
Tem.
At.
Com.
0.000004
1143
1082
0.000003
1129
1078
0.000003
1098
1045
0.000002
1019
944
100000
Tem.
At.
Com.
0.006494
2151822
3113250
0.003207
2142838
3103031
0.003237
2092234
3039101
0.004112
1997608
2926715

Tem.
0.000018
0.000018
0.000018
0.000015

At.
14711
14589
14249
13319

1000
Com.
17583
17401
17008
15965

Tem.
0.000252
0.000232
0.000386
0.000210

At.
10000
10000
10000
10000

1000
Com.
5052
8154
8700
4932

Tem.
0.000486
0.000155
0.000184
0.000112

Tem.
0.047151
0.051148
0.051224
0.045305

Tabela 8: MergeSort Otimizado


Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente
Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente

At.
40
40
40
40
At.
140000
140000
140000
140000

10
Com.
21
22
21
15
10000
Com..
71712
116662
123472
64749

MergeSort Otimizado
100
At.
Com.
700
372
700
504
700
560
700
316
100000
Tem.
At.
Com.
0.001624
1700000
877968
0.002483
1700000
1076802
0.002505
1700000
1564552
0.001522
1700000
816361
Tem.
0.000004
0.000004
0.000004
0.000003

Tem.
0.000012
0.000015
0.000016
0.000011
Tem.
0.019310
0.029665
0.045945
0.021986

Tabela 9: QuickSort Otimizado


Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente
Elementos
Ordenado
Quase Ordenado
Aleatrio
Inversamente

At.
27
27
27
27
At.
29167
40888
79301
44032

10
Com.
45
45
45
45
10000
Com..
177511
162276
155573
166712

QuickSort Otimizado
100
Tem.
At.
Com.
0.000013
283
840
0.000004
326
865
0.000004
439
924
0.000004
433
754
100000
Tem.
At.
Com.
0.001382
286372
1828462
0.001602
403955
1859209
0.002246
970996
1780578
0.001527
435040
1723642

Tem.
0.000013
0.000014
0.000018
0.000018

At.
2871
3626
6192
4371

1000
Com.
12782
13127
12127
11802

Tem.
0.000114
0.000160
0.000178
0.000118

Tem.
0.013914
0.018154
0.026545
0.015736

Como pode ser observado nas tabelas acima, o QuickSort Executa menor nmero
de atribuies para as diversas disposies dos vetores. Considerando o nmero de
comparaes, o MergeSort executa menor nmero de comparaes para as diversas
disposies dos vetores. Para vetores at 1000 posies, o MergeSort tem ligeiramente um tempo menor de execuo e para vetores acima desse valor o QuickSort se
torna mais rpido que os dois. Pelos dados analisados, o QuickSort foi considerado
o mtodo mais eficiente dentre estes.

24

2.10

Mtodos Simples x Mtodos Eficientes

No h dvidas que para vetores com grande nmero de elementos os mtodos


ditos eficientes so muito melhores que os mtodos simples. Mas os mtodos eficientes no so to rapidos para um nmero pequeno de elementos no vetor, sendo
facilmente superados pelos mtodos ditos simples. A questo : at nmero de
elementos compensa se usar os mtodos simples? Foram feitos teste com o melhor
algoritmo de cada classe: InsertSort e QuickSort.
Tabela 10: Eficientes x Simples
Eficientes x Simples
Elem.
30
50
70
Bubble
Quick
Bubble
Quick
Bubble
Quick
Temp.
Temp.
Temp.
Temp.
Temp.
Temp.
Ord 0.000002 0.000013 0.000002 0.000007 0.000002 0.000010
Q Ord 0.000002 0.000006 0.000004 0.000008 0.000006 0.000010
Ale 0.000004 0.000007 0.000008 0.000010 0.000012 0.000013
Inv 0.000007 0.000006 0.000015 0.000007 0.000028 0.000010
De acordo a tabela acima, para vetores com menos de 70 elementos, recomendvel usar os mtodos simples(InsertSort) e para vetores acima deste valor deve-se
usar os mtodos eficientes(QuickSort).

25

Testes

Foram executados alguns testes para vetores de 10, 100, 1000, 10000 e 100000
elementos ordenados, quase ordenados, aleatrios e inversamente ordenados.

3.1

Vetor Ordenado

As tabelas abaixo apresentam o nmero de atribuies, comparaes e tempo de


execuo em um vetor ordenado para todos os algoritmos.
Tabela 11: Atribuies para um vetor ordenado
Vetor Ordenado
Elementos
10
100
1000 10000 100000
Atri. Atri. Atri.
Atri.
Atri.
Bubble
0
0
0
0
0
Select
0
0
0
0
0
Insert
18
198
1998 19998 199998
Heap
83
83
14711 181460 2151822
Merge
40
700 10000 140000 1700000
Quick
27
283
2871 29167 286372

Tabela 12: Comparaes para um vetor ordenado


Vetor Ordenado
Elementos
10
100
1000
10000
100000
Comp. Comp. Comp.
Comp.
Comp.
Bubble
9
99
999
9999
99999
Select
45
4950 499500 49995000 704982704
Insert
0
0
0
0
0
Heap
41
1082
17583
244488
3113250
Merge
21
372
5052
71712
877968
Quick
45
840
12782
177511
1828462

Tabela 13: Tempo de execuo para um vetor ordenado


Vetor Ordenado
Elementos
10
100
1000
10000
100000
Temp.
Temp.
Temp.
Temp.
Temp.
Bubble
0.000002 0.000003 0.000009 0.000079 0.000806
Select
0.000002 0.000038 0.004428 0.402462 704982704
Insert
0.000002 0.000003 0.000016 0.000136 0.001449
Heap
0.000004 0.000018 0.000252 0.006494 0.047151
Merge
0.000004 0.000012 0.000486 0.001624 0.019310
Quick
0.000013 0.000013 0.000114 0.001382 0.013914

26

Abaixo so apresentados os grficos com o nmero de atribuies e comparaes


em um vetor ordenado para todos os algoritmos.

Figura 8: Grficos de atribuies

Figura 9: Grficos de comparaes

27

3.2

Vetor Quase Ordenado

As tabelas abaixo apresentam o nmero de atribuies, comparaes e tempo de


execuo em um vetor quase ordenado para todos os algoritmos.
Tabela 14: Atribuies para um vetor quase
Vetor Quase Ordenado
Elementos
10
100
1000
10000
Atri. Atri. Atri.
Atri.
Bubble
3
1155 175656 16936458
Select
3
30
300
3000
Insert
23
786
62624 5771960
Heap
84
1129 14589
180121
Merge
40
700
10000
140000
Quick
27
326
3626
40888

ordenado
100000
Atri.
435576432
30000
143452426
2142838
1700000
403955

Tabela 15: Comparaes para um vetor quase ordenado


Vetor Quase Ordenado
Elementos
10
100
1000
10000
100000
Comp. Comp. Comp.
Comp.
Comp.
Bubble
17
4209 498510 49985684 65833800
Select
45
4950 499500 49995000 704982704
Insert
5
588
60626 5751962 49994714
Heap
41
1078
17401
242597
3103031
Merge
22
504
8154
116662
1076802
Quick
45
865
13127
162276
162276

Tabela 16: Tempo de execuo para um vetor quase


Vetor Quase Ordenado
Elementos
10
100
1000
10000
Temp.
Temp.
Temp.
Temp.
Bubble
0.000002 0.000045 0.004870 0.549886
Select
0.000002 0.000039 0.004086 0.404392
Insert
0.000002 0.000009 0.000830 0.062947
Heap
0.000003 0.000018 0.000232 0.003207
Merge
0.000004 0.000015 0.000155 0.002483
Quick
0.000004 0.000014 0.000160 0.001602

28

ordenado
100000
Temp.
26.240775
40.179751
1.521.799
0.051148
0.029665
0.018154

Abaixo so apresentados os grficos com o nmero de atribuies e comparaes


em um vetor quase ordenado para todos os algoritmos.

Figura 10: Grficos de atribuies

Figura 11: Grficos de comparaes

29

3.3

Vetor Aleatrio

As tabelas abaixo apresentam o nmero de atribuies, comparaes e tempo de


execuo em um vetor aleatrio para todos os algoritmos.
Tabela 17: Atribuies para um vetor aleatrio
Vetor Aleatrio
Elementos
10
100
1000
10000
100000
Atri. Atri. Atri.
Atri.
Atri.
Bubble
39
6714 664107 68328030 1810376450
Select
18
189
2154
21762
217539
Insert
35
2331 197775 20090389 2027818515
Heap
81
1098 14249
175801
2092234
Merge
40
700
10000
140000
1700000
Quick
27
439
6192
79301
970996

Tabela 18: Comparaes para um vetor aleatrio


Vetor Aleatrio
Elementos
10
100
1000
10000
100000
Comp. Comp. Comp.
Comp.
Comp.
Bubble
45
4905 498905 49978710 704930378
Select
45
4950 499500 49995000 704930378
Insert
17
2133 195777 20070391 2027618517
Heap
40
1045
17008
237101
3039101
Merge
21
560
8700
123472
1564552
Quick
45
924
12127
155573
1780578

Tabela 19: Tempo de execuo para um vetor aleatrio


Vetor Aleatrio
Elementos
10
100
1000
10000
100000
Temp.
Temp.
Temp.
Temp.
Temp.
Bubble
0.000002 0.000081 0.008100 0.912763 81.658714
Select
0.000002 0.000002 0.004035 0.393090 40.197.262
Insert
0.000002 0.000024 0.002078 0.223080 21.936.880
Heap
0.000003 0.000018 0.000018 0.003237 0.051224
Merge
0.000004 0.000016 0.000184 0.002505 0.045945
Quick
0.000004 0.000018 0.000178 0.002246 0.026545

30

Abaixo so apresentados os grficos com o nmero de atribuies e comparaes


em um vetor aleatrio para todos os algoritmos.

Figura 12: Grficos de atribuies

Figura 13: Grficos de comparaes

31

3.4

Vetor Inversamente ordenado

As tabelas abaixo apresentam o nmero de atribuies, comparaes e tempo de


execuo em um vetor inversamente ordenado para todos os algoritmos.
Tabela 20: Atribuies para um vetor inversamente ordenado
Vetor Inversamente Ordenados
Elementos
10
100
1000
10000
100000
Atri. Atri.
Atri.
Atri.
Atri.
Bubble
135 14847 1498500 149984142 2114940093
Select
15
153
1500
15858
158019
Insert
63
5147 501498 50014712 705180029
Heap
74
1019
13319
166682
1997608
Merge
40
700
10000
140000
1700000
Quick
27
433
4371
44032
435040

Tabela 21: Comparaes para um vetor inversamente ordenado


Vetor Inversamente Ordenados
Elementos
10
100
1000
10000
100000
Comp. Comp. Comp.
Comp.
Comp.
Bubble
45
4950 499500 49995000 704930378
Select
45
4950 499500 49995000 704930378
Insert
45
4949 499500 49994714 704930378
Heap
35
944
15965
226720
2926715
Merge
15
316
4932
64749
816361
Quick
45
754
11802
166712
1723642

Tabela 22: Tempo de execuo para um vetor inversamente ordenado


Vetor Inversamente Ordenados
Elementos
10
100
1000
10000
100000
Temp.
Temp.
Temp.
Temp.
Temp.
Bubble
0.000003 0.000099 0.010459 1.149.139 111.727621
Select
0.000002 0.000042 0.004115 0.420611 43.305694
Insert
0.000002 0.000053 0.005270 0.536122 55.268314
Heap
0.000002 0.000015 0.000210 0.004112
0.045305
Merge
0.000003 0.000011 0.000112 0.001522
0.021986
Quick
0.000004 0.000018 0.000118 0.001527
0.015736

32

Abaixo so apresentados os grficos com o nmero de atribuies e comparaes


em um vetor inversamente ordenado para todos os algoritmos.

Figura 14: Grficos de atribuies

Figura 15: Grficos de comparaes

33

Concluso

Este trabalho possibilitou um aprofundamento sobre os algoritmos de ordenao


vistos em sala de aula bem como a anlise do nmero de atribuies, comparaes e
tempo de execuo de forma bem eficiente. Pelos testes executados pde-se concluir
que:
Vale a pena inserir a verificao de ordenao (houve troca) no algoritmo
BubbleSort;
No vale a pena usar o algoritmo InsertSort com elemento sentinela;
Vale a pena inserir uma verificao (Min == i) para evitar a troca, no mtodo
SelectSort.
O QuickSort o algoritmo mais eficiente para ordenar vetores de grandes
dimenses
Vale a pena usar os algoritmos simples at vetores de 70 elementos, acima
desse valor deve-s usar os algoritmos eficientes
As dificuldades encontradas foram devido ao fato haver vrias alteraes no cdigo, implementao do InsertSort com cursores e de gerar os grficos com eficincia.
As mesmas foram sanadas com o auxilio da bibliografia citada e a ajuda do professor
e monitores.

34

Referncias
[1] David Menotti. Ordenaao, November 2009.
[2] N. Ziviani. Projeto de Algoritmos: com implementaes em Pascal e C. Cengage
Learning (Thomson / Pioneira), So Paulo, 2nd edition, 2004.

35