Merge Sort¶
O Merge sort divide um array em metades, ordena-as recursivamente e intercala os dois intervalos ordenados. Seu tempo de execução previsível e sua estabilidade o tornam um algoritmo fundamental de ordenação por comparação.
static void mergeSort(int[] values) {
int[] buffer = new int[values.length];
mergeSort(values, buffer, 0, values.length);
}
private static void mergeSort(int[] values, int[] buffer, int low, int high) {
if (high - low < 2) return;
int middle = low + (high - low) / 2;
mergeSort(values, buffer, low, middle);
mergeSort(values, buffer, middle, high);
merge(values, buffer, low, middle, high);
}
private static void merge(
int[] values, int[] buffer, int low, int middle, int high) {
System.arraycopy(values, low, buffer, low, high - low);
int left = low;
int right = middle;
for (int destination = low; destination < high; destination++) {
if (left >= middle) values[destination] = buffer[right++];
else if (right >= high) values[destination] = buffer[left++];
else if (buffer[left] <= buffer[right]) values[destination] = buffer[left++];
else values[destination] = buffer[right++];
}
}
Correção¶
Use indução sobre o comprimento do intervalo. Intervalos de comprimento zero ou um estão ordenados. Supondo que as duas chamadas recursivas ordenem suas metades menores, o laço de intercalação mantém o invariante de que o prefixo da saída contém, em ordem, os menores elementos já consumidos. Ao término, o intervalo inteiro está ordenado e contém exatamente os elementos originais.
Complexidade¶
A recorrência T(n) = 2T(n/2) + Θ(n) resulta em tempo Θ(n log n) em todos os
casos. O buffer compartilhado usa espaço auxiliar Θ(n), e a recursão usa
Θ(log n) quadros de pilha. O pico de espaço auxiliar é Θ(n), não
Θ(n log n). Esta implementação é estável porque, em caso de empate, primeiro
retira o elemento da metade esquerda, mas não é in-place.