Algoritmos de ordenação

Propaganda
Algoritmos de ordenação
Ordenação rápida (“Quicksort”)
➔ Baseia-se num princípio muito simples que, quando aplicado de forma
recursiva, acaba por ordenar o vetor.
➔ Este princípio é composto por 2 passos essenciais:
1. Escolher um elemento do vetor, o pivot (por ex., V1);
2. Dividir o vetor em 2 partes (esquerda e direita), em que:
✔ Parte esquerda com os elementos menores do que o pivot;
✔ Parte direita com os elementos maiores do que o pivot.
➔ Ao ser aplicado succesivamente este princípio a ambas as partes, quando
o processo recursivo terminar o vetor está ordenado.
Algoritmos de ordenação
Ordenação rápida (“Quicksort”)
O algoritmo é composto então por 3 etapas:
1. Determinar a posição final (posPivot) do elemento pivot (por ex. V1) no
vetor e colocá-lo nessa posição, dividindo o vetor em 2 partes:
✔ Esquerda = V1, ..., VposPivot - 1
✔ Direita = VposPivot + 1, ..., VN
2. Aplicar o algoritmo recursivamente à parte esquerda;
3. Aplicar o algoritmo recursivamente à parte direita.
Algoritmos de ordenação
Quicksort (Algoritmo)
Ordenar por Quicksort um subvetor de V desde inicio até fim
Se (inicio < fim) então
posPivot  posição final do pivot, Vinicio, no vetor
Ordenar por Quicksort o subvetor esquerdo ao pivot
Ordenar por Quicksort o subvetor direito ao pivot
Note-se que se (inicio >= fim) então o subvetor de V tem
- apenas um elemento (inicio = fim) ou
- está vazio (inicio > fim).
Logo, este subvetor está ordenado.
Algoritmos de ordenação
Quicksort (Algoritmo)
Determinar a posição final posPivot do pivot (Vinicio) no subvetor de
V desde inicio até fim
posPivot  inicio
Para k desde (inicio+1) até fim fazer
Se (Vk < Vinicio) então
posPivot  posPivot + 1
Trocar(VposPivot, Vk)
Trocar(VposPivot, Vinicio)
{ Resultado = posPivot }
Algoritmos de ordenação
Quicksort (em MatLab)
function [V] = OrdenarQuicksort (V, inicio, fim)
if inicio < fim
[posPivot, V] = DeterminarPivot(V, inicio, fim);
V = OrdenarQuicksort(V, inicio, posPivot - 1);
V = OrdenarQuicksort(V, posPivot + 1, fim);
end;
Algoritmos de ordenação
Quicksort (em MatLab)
function [posPivot, V] = DeterminarPivot(V, inicio, fim)
posPivot = inicio;
for k = inicio+1:fim
if V(k) < V(inicio)
posPivot = posPivot + 1;
[V(k), V(posPivot)] = Trocar(V(k), V(posPivot));
end;
end;
[V(inicio), V(posPivot)] = Trocar(V(inicio), V(posPivot));
Algoritmos de ordenação
Quicksort (em MatLab)
function [a, b] = Trocar (a, b)
c = a;
a = b;
b = c;
Algoritmos de ordenação
Ordenação por fusão (“Merge Sort”)
➔ A ordenação por fusão consiste em
✔ dividir o vetor em vários subvetores de menor dimensão,
✔ ordenar estes subvetores separadamente e,
✔ fundi-los num vetor único.
➔ O algoritmo de ordenação por fusão é recursivo e consiste em
✔ dividir sucessivamente o vetor ao meio até que se obtenham
subvetores com apenas um elemento (que está ordenado)
✔ fundir os subvetores num vetor único.
Algoritmos de ordenação
Ordenação por fusão (“Merge Sort”)
Pretende-se que o algoritmo de ordenação por fusão:
1. Ordene um vetor V entre as posições
a e b : Va, Va+1, ..., Vb e
b+1 e c : Vb+1, Vb+2, ..., Vc;
2. Fundir um vetor V entre as posições a e c, tendo em conta que está
ordenado entre as posições
a e b : Va ≤ Va+1 ≤ ... ≤ Vb e
b+1 e c : Vb+1 ≤ Vb+2 ≤ ... ≤ Vc.
Algoritmos de ordenação
Ordenação por fusão (“Merge Sort”)
Ordenar por fusão um vetor V entre as posições inicio e fim
Se (inicio < fim) então
meio  (inicio + fim) / 2
Ordenar por fusão o vetor V entre as posições inicio e meio
Ordenar por fusão o vetor V entre as posições meio+1 e fim
Fundir os subvetores de V entre [inicio, meio] e [meio+1, fim]
Note-se que se inicio ≥ fim então o vetor é composto
- apenas por um elemento (inicia = fim) ou
- está vazio (inicio > fim).
Logo, está ordenado.
Algoritmos de ordenação
Ordenação por fusão (em MatLab)
function [V] = OrdenarFusao (V, inicio, fim)
if inicio < fim
meio = floor((inicio + fim) / 2);
V = OrdenarFusao(V, inicio, meio);
V = OrdenarFusao(V, meio + 1, fim);
V = Fusao(V, inicio, meio, fim);
end;
Algoritmos de ordenação
Ordenação por fusão (em MatLab)
function [V] = Fusao(V, inicio, meio, fim)
esq = inicio;
dir = meio + 1;
k = 0;
while esq <= meio & dir <= fim
k = k + 1;
if V(esq) < V(dir)
Aux(k) = V(esq);
esq = esq + 1;
else
Aux(k) = V(dir);
dir = dir + 1;
end;
end;
Algoritmos de ordenação
Ordenação por fusão (em MatLab) – cont.
if esq > meio
for i = dir:fim
k = k + 1;
Aux(k) = V(i);
end;
else
for i = esq:meio
k = k + 1;
Aux(k) = V(i);
end;
end;
for i = 0:k-1
% passar o vetor Aux ordenado para o vetor V
V(inicio+i) = Aux(i+1);
end;
Download