Professional Documents
Culture Documents
2007/08
A.E.D.
F.S.B.
Algoritmo de ShellSort
Inventado por Donald Shell
Neste caso percorre-se o vector ordenando apenas
elementos que se encontram afastados
Para ordenar estes usa-se o algoritmo de inserção
À distância entre elementos chama-se incremento
Depois destes estarem ordenados ordenam-se os
mais próximos até se ordenarem os elementos
adjacentes
Ou seja, vai-se diminuindo o incremento até este ser 1
Como a distância entre elementos se aproxima de 1
este algoritmo também se costuma chamar
Ordenação por incrementos decrescentes
Ordenação de vectores : ShellSort
2007/08
A.E.D.
F.S.B.
do{
h /= 3; // actualizar o h para esta iteração
for( int i = h; i < v.length; i+= h ) {
int x = v[ i ];
int j = i;
while( j > 0 && v[ j-h ] > x ){
v[ j ] = v[ j-h ];
j -= h;
}
v[ j ] = x;
}
} while( h > 1 );
}
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Algoritmo de MergeSort
Algoritmo recursivo
Divide o vector a meio, formando dois vectores
ordena-os separadamente
reagrupa-os num novo vector
Para ordenar os vectores resultantes aplica o mesmo
raciocínio
Obriga a criar um novo vector por causa do
reagrupamento
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Divisão em sub-vectores
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Neste ponto coloca-se outro problema:
Como se juntam dois vectores, já ordenados de modo
a ficarem um só vector?
O algoritmo é simples:
Verifica-se qual dos dois vectores tem o menor
número na posição inicial
Coloca-se esse elemento na primeira posição de um
novo vector
Passa-se ao elemento seguinte no vector de onde se
retirou o elemento
No vector cujo elemento não foi retirado mantém-se na
mesma posição
Repete-se o algoritmo para os restantes elementos
dos vectores, actualizando sempre o vector que foi
alterado
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Caso de junção de vectores
2 i2 = 0 2 i2 = 0 2 2 2 2
5 5 5 i2 = 1 5 i2 = 1 5 i2 = 1 5
7 7 7 7 7 7
8 8 8 8 8 8
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Caso de junção de vectores
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Reagrupar os subvectores
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Reagrupar os subvectores
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Reagrupar os subvectores
1ª chamada 2ª chamada
9 9 esq = 0 3 2
9 9 esq = 0 3 3 5 3
3 3 5 5 centro = 2 9 5
5 5 11 11 9
11 11 2 2 dir = 4 11
2
2 2 centro = 4
11
7 7
12 12 7
6 6 12
8 8 dir = 8 6
8
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Reagrupar os subvectores
1ª chamada 2ª chamada
2 2 esq = 0 3 2
9 9 esq = 0 3 3 5 3
3 3 5 5 centro = 2 9 5
5 5 9 9 9
11 11 11 11 dir = 4 11
2
2 2 centro = 4
11
7 7
12 12 6
6 6 7
8 8 dir = 8 8
12
Este vector também foi alterado
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Reagrupar os subvectores
1ª chamada
2
9 9 esq = 0 3 2
3 3 5 3
5 5 9 5
11 11 11 6
2 2 centro = 4 7
7 7 8
12 12 6 9
6 6 7 11
8 8 dir = 8 8 12
12
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Reagrupar os subvectores
1ª chamada
2
2 2 esq = 0 3 2
3 3 5 3
5 5 9 5
6 6 11 6
7 7 centro = 4 7
8 8 8
9 9 6 9
11 11 7 11
12 12 dir = 8 8 12
12
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
O algoritmo MergeSort para ser implementado
exigue vários métodos:
O método inicial cria o vector novo e começa a
chamada recursiva
O método que é recursivo e vai partindo os vectores a
meio
O método que faz o reagrupamento
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
O método inicial cria o vector novo e começa a
chamada recursiva, pode ser assim
implementado
void mergeSortRec( int v[], int vAux[], int esq, int dir ) {
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
O método que faz o reagrupamento, pode ser
assim implementado
void reagrupar( int v[], int vAux[], int i1, int i2, int fim2 ) {
// a primeira parte do vector vai de i1 a i2-1
int fim1 = i2-1;
// e a segunda de i2 a fim
// … continua no seguinte
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
O método que faz o reagrupamento, pode ser
assim implementado
// … continuação do anterior
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Algoritmo de QuickSort
Algoritmo recursivo
Mais rápido algoritmo de ordenação existente
Primeiro é escolhido um valor (pivot)
Divide o vector em duas partes
A primeira parte com elementos menores que o pivot
A segunda parte com elementos maiores que o pivot
O pivot é colocado no meio das duas partes
Para ordenar as partes dai resultantes aplica-se o
mesmo raciocínio
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo
Usando um pivot completamente arbitrário!
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo
Usando um pivot completamente arbitrário!
9 9 6 6 2 2 2
pivot = 2
3 3 3 <7 3 3 <5 3 3
pivot = 5
5 5 5 5 5
11 11 2 2 6 >5
2 2 7
7 7 pivot = 7 12
12 12 9 >7
6 6 8
8 8 11
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo
Usando um pivot completamente arbitrário!
9 9 6 6 2 2
3 3 3 <7 3 3 3
pivot = 5
5 5 5 5 5
11 11 2 2 6
2 2 7
7 7 pivot = 7 12 Vindo de outra chamada
12 12 9 >7
6 6 8
8 8 11
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo
Usando um pivot completamente arbitrário!
1ª chamada 2ª chamada
9 9 6 2 2
3 3 3 <7 3 3
pivot = 5
5 5 5 5 5
11 11 2 6 6
2 2 7
7 7 pivot = 7 12
12 12 9 >7
6 6 8
8 8 11
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo
Usando um pivot completamente arbitrário!
1ª chamada 2ª chamada
9 9 2 2
3 3 3 3
5 5 5 5
11 11 6 6
2 2 7
7 7 pivot = 7 8
12 12 9
6 6 11
8 8 12
Vindo de outra chamada
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo
Usando um pivot completamente arbitrário!
1ª chamada
2 2 2
3 3 3
5 5 5
6 6 6
7 7 7
8 8 pivot = 7 8
9 9 9
11 11 11
12 12 12
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Visto assim o QuickSort até é fácil de
compreender, mas há pontos ainda em aberto:
Como se escolhe o pivot?
Como se coloca o pivot no centro do vector?
Como se divide o vector em maiores e menores?
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Escolha do pivot:
Não se deve escolher o primeiro elemento
Num vector já ordenado isso iria dividir o vector em dois
pedaços: um com um elemento (o pivot) e outro com o resto
dos elementos todos…
Não se deve escolher o último
Pelas mesmas razões
Um muito utilizado é usar a mediana de três valores
Os valores a utilizar são o primeiro, o último e o central
Escolhe-se aquele que for o valor do meio
Outra técnica é escolher um aleatoriamente
Requer um gerador de números aleatórios
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Colocação do pivot no centro do vector:
Normalmente coloca-se no final do vector
Só depois da divisão em maiores e menores é que se
recoloca no meio
Para isso troca-se o pivot com o penúltimo elemento do
vector
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Escolha do pivot:
Pode ser feita com este método
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Como se divide o vector em maiores e menores?
Existem várias técnicas
Uma muito usada é ter dois índices a percorrer o
vector
Um da esquerda para a direita
Outro da direita para a esquerda
Quando o da esquerda detecta um maior que o pivot
pára
Quando o da direita detecta um menor que o pivot
pára
Quando ambos param trocam os seus valores
Quando ambos se encontram é porque o vector já
está dividido
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo de divisão em maiores e menores
Usando um pivot mediana de 3
v[ini] > v[centro] trocam pivot está no centro Vector pronto para dividir
9 ini = 0 9 2 2 2 2
3 3 3 3 3 3
5 5 5 5 5 5
11 11 11 11 11 11
2 centro = 4 2 9 8 8 6
7 7 7 7 7 7
12 12 12 12 12 12
6 6 6 6 6 8
8 fim = 8 8 8 9 9 9
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo de divisão em maiores e menores
Usando um pivot mediana de 3
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
A divisão em maiores e menores pode ser feita
com este método
void divideMaioresMenores( int v[], int ini, int fim, int pivot ) {
int i = ini;
int j = fim -1;
while( i < j ) {
while( v[ ++i ] < pivot );
while( v[ --j ] > pivot );
if( i < j )
troca( v, i, j );
}
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Tal como no MergeSort o algoritmo exige, pelo
menos, dois métodos:
O que prepara a chamada recursiva
O que faz as chamadas recursivas
quickSortRec( v, 0, v.length -1 );
}
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
O que faz as chamadas recursivas
// determinar o pivot
int pivot = pivotMediana( v, ini, fim );
2007/08
A.E.D.
F.S.B. Ordenação de vectores : BucketSort
Mais rápido ainda que o QuickSort!
Mas o QuickSort não era o mais rápido?
Não é genérico!
Só serve para valores numéricos inteiros positivos
Embora com adaptações sirva para negativos
O QuickSort serve para tudo, logo é o mais rápido dos
genéricos
Temos de ter a certeza que os números nunca
são maiores que um dado valor
2007/08
A.E.D.
F.S.B. Ordenação de vectores : BucketSort
Cria-se um vector com o tamanho do maior
número presente no vector a ordenar, chamado
vector de contagem
Inicializa-se cada posição do vector de
contagem a zero
Percorre-se o vector a ordenar
Por cada elemento do vector incrementa-se no vector
de contagem a posição correspondente ao seu valor
Exemplo: o número 5 iria fazer incrementar de 1 a posição 5
do vector de contagem
No final é só alterar o vector original de acordo
com a contagem feita no vector de contagem
2007/08
A.E.D.
F.S.B. Ordenação de vectores : BuckerSort
Exemplificação do algoritmo
Assume-se que o valor mais alto que se pode ordenar é o 14
Vector de contagem,
com 15 posições
0
0
2 1 Ocorrência de 2 incrementa posição 2 do vector
3 1 Ocorrência de 3 incrementa posição 3 do vector
5 0
5 2 2 ocorrências de 5 incrementa duas vezes a posição 5 do vector
12 0
7 1 Ocorrência de 7 incrementa posição 7 do vector
12 1 Ocorrência de 8 incrementa posição 8 do vector
8 1 Ocorrência de 9 incrementa posição 8 do vector
9 0
2 2 ocorrências de 12 incrementa duas vezes a posição 12 do vector
0 Vector de contagem completo
0 Falta repor o vector de origem
0
2007/08
A.E.D.
F.S.B. Ordenação de vectores : BuckerSort
Exemplificação do algoritmo
Assume-se que o valor mais alto que se pode ordenar é o 14
Vector de contagem,
com 15 posições
0 Não há zeros nem uns no vector original
0
2 1 Copia 1 vez o 2 para o vector original
3 1 Copia 1 vez o 3 para o vector original
5 0
5 2 Copia 2 vezes o 5 para o vector original
7 0
8 1 Copia 1 vez o 7 para o vector original
9 1 Copia 1 vez o 8 para o vector original
12 1 Copia 1 vez o 9 para o vector original
12 0
2 Copia 2 vezes o 12 para o vector original
0
0
0
2007/08
A.E.D.
F.S.B. Ordenação de vectores : BucketSort
Este algoritmo pode ser assim implementado