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;