Escolar Documentos
Profissional Documentos
Cultura Documentos
ALGORITMOS DE
ORDENAÇÃO RECURSIVOS
Ideia
- Baseia-se num princípio muito simples que, quando aplicado recursivamente,
acaba por ordenar um vetor V.
- Este princípio baseia-se no seguinte:
1. Escolher um elemento do vetor, o pivot (por ex., V[0])
2. Colocar o pivot na sua posição final (ordenado)
3. 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 ou iguais ao pivot.
- Ao ser aplicado sucessivamente este princípio à partes esquerda e direita, o
processo recursivo quando terminar apresenta o vetor ordenado.
Algoritmo
- Pretende-se ordenar um vetor V entre as posições inicio e fim
- inicialmente: inicio = 0 e fim = N-1
- O algoritmo é composto pelos seguintes passos:
1. Determinar a posição final k do elemento pivot (V[inicio]) em V
2. Colocar o pivot na posição k, ficando o vetor V dividido em 2 partes:
- Esquerda = V[inicio], ..., V[k-1]
- Direita = V[k+1], ..., V[fim]
3. Aplicar o algoritmo recursivamente à parte esquerda;
4. Aplicar o algoritmo recursivamente à parte direita.
Algoritmo principal
- Ordenar por Quicksort um sub-vetor de V desde inicio até fim
Se (inicio < fim) então
k posição final do pivot, V[inicio], no vetor V
Ordenar por Quicksort o sub-vetor esquerdo ao pivot
Ordenar por Quicksort o sub-vetor direito ao pivot
- Nota:
Se (inicio >= fim) então o sub-vetor de V tem
- apenas um elemento (inicio = fim) ou
- está vazio (inicio > fim).
Logo, este sub-vetor está ordenado.
Função principal
void OrdenarQuicksort (int V[], int inicio, int fim) {
int k; // k = posição final do pivot V[inicio] em V ordenado
if (inicio < fim) {
k = DeterminarPosicaoPivot(V, inicio, fim);
OrdenarQuicksort(V, inicio, k-1);
OrdenarQuicksort(V, k+1, fim);
}
}
Função auxiliar 1
int DeterminarPosicaoPivot (int V[], int inicio, int fim) {
int i, k = inicio; // k = posição final do pivot (V[inicio]) em V ordenado
for (i = inicio+1; i <= fim; i++)
if (V[i] < V[inicio]){
k++;
Trocar(&V[i], &V[k]);
}
Trocar(&V[inicio], &V[k]);
return k;
}
Função auxiliar 2
void Trocar (int *a, int *b){
int aux;
aux = *a;
*a = *b;
*b = aux;
}
Ideia
- dividir o vetor em vários sub-vetores de menor dimensão,
- ordenar estes sub-vetores separadamente e,
- fundi-los num vetor único.
O algoritmo consiste em
- dividir sucessivamente o vetor ao meio até que se obtenham sub-vetores com
apenas 1 elemento (que está ordenado)
- fundir os sub-vetores num vetor único.
Algoritmo
- Pretende-se ordenar um vetor V entre as posições a e c
- O algoritmo é composto por 2 partes:
1. Ordenar o vetor V entre as posições
- a e b (V[a], V[a+1], ..., V[b]), e
- b+1 e c (V[b+1], V[b+2], ..., V[c]);
2. Fundir o vetor V entre as posições a e c, pois está ordenado entre as posições
- a e b (V[a] ≤ V[a+1] ≤ ... ≤ V[b]) e
- b+1 e c (V[b+1] ≤ V[b+2] ≤ ... ≤ V[c]).
Algoritmo
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 sub-vetores de V entre [inicio, meio] e [meio+1, fim]
Nota:
Se (inicio ≥ fim) então o vetor V é composto
- apenas por um elemento (inicio = fim) ou
- está vazio (inicio > fim).
Logo, está ordenado.
Função
void OrdenarFusao (int V[], int inicio, int fim) {
int meio;
if (inicio < fim) {
meio = (inicio + fim) / 2;
OrdenarFusao(V, inicio, meio);
OrdenarFusao(V, meio+1, fim);
Fusao(V, inicio, meio, fim);
}
}
Função auxiliar
void Fusao (int V[], int inicio, int meio, int fim) {
int esq = inicio, dir = meio+1, k = 0, Aux[fim-inicio+1];
while ((esq <= meio) && (dir <= fim)) {
if (V[esq] < V[dir]) {
Aux[k] = V[esq];
esq++;
}
else {
Aux[k] = V[dir];
dir++;
}
k++;
}