Mesclar classificação em Java
1. Introdução
Neste tutorial, daremos uma olhada emthe Merge Sort algorithm and its implementation in Java.
A classificação por mesclagem é uma das técnicas de classificação mais eficientes e é baseada no paradigma "dividir para conquistar".
2. O Algoritmo
Merge sort is a “divide and conquer” algorithm wherein we first divide the problem into subproblems. Quando as soluções para os subproblemas estão prontas, nós as combinamos para obter a solução final para o problema.
Este é um dos algoritmos que podem ser facilmente implementados usando a recursão, pois lidamos com os subproblemas e não com o problema principal.
O algoritmo pode ser descrito como o seguinte processo de 2 etapas:
-
Divide: In this step, we divide the input array into 2 halves, o pivô sendo o ponto médio da matriz. Essa etapa é executada recursivamente para todas as meias matrizes até que não haja mais meias matrizes para dividir.
-
Conquer: In this step, we sort and merge the divided arrays de baixo para cima e obtém o array ordenado.
O diagrama a seguir mostra o processo completo de classificação de mesclagem para uma matriz de exemplo \ {10, 6, 8, 5, 7, 3, 4}.
Se olharmos mais de perto o diagrama, podemos ver que a matriz é recursivamente dividida em duas metades até que o tamanho se torne 1. Depois que o tamanho se torna 1, os processos de mesclagem entram em ação e começam a mesclar matrizes de volta ao classificar:
3. Implementação
Para a implementação,we’ll write a mergeSort function which takes in the input array and its length como parâmetros. Esta será uma função recursiva, por isso precisamos da base e das condições recursivas.
A condição base verifica se o comprimento da matriz é 1 e ele retornará. Nos demais casos, a chamada recursiva será executada.
For the recursive case, we get the middle index and create two temporary arrays l[] and r[]. A funçãomergeSort é então chamada recursivamente para ambas as submatrizes:
public static void mergeSort(int[] a, int n) {
if (n < 2) {
return;
}
int mid = n / 2;
int[] l = new int[mid];
int[] r = new int[n - mid];
for (int i = 0; i < mid; i++) {
l[i] = a[i];
}
for (int i = mid; i < n; i++) {
r[i - mid] = a[i];
}
mergeSort(l, mid);
mergeSort(r, n - mid);
merge(a, l, r, mid, n - mid);
}
We then call the merge function which takes in the input and both the sub-arrays and the starting and end indices of both the sub arrays.
A funçãomerge compara os elementos de ambas as submatrizes um por um e coloca o elemento menor na matriz de entrada.
Quando chegamos ao final de uma das sub-matrizes, o restante dos elementos da outra matriz é copiado na matriz de entrada, fornecendo-nos a matriz final classificada:
public static void merge(
int[] a, int[] l, int[] r, int left, int right) {
int i = 0, j = 0, k = 0;
while (i < left && j < right) {
if (l[i] <= r[j]) {
a[k++] = l[i++];
}
else {
a[k++] = r[j++];
}
}
while (i < left) {
a[k++] = l[i++];
}
while (j < right) {
a[k++] = r[j++];
}
}
O teste de unidade para o programa:
@Test
public void positiveTest() {
int[] actual = { 5, 1, 6, 2, 3, 4 };
int[] expected = { 1, 2, 3, 4, 5, 6 };
MergeSort.mergeSort(actual, actual.length);
assertArrayEquals(expected, actual);
}
4. Complexidade
Como a classificação por mesclagem é um algoritmo recursivo, a complexidade do tempo pode ser expressa como a seguinte relação recursiva:
T(n) = 2T(n/2) + O(n)
2T(n/2) corresponde ao tempo necessário para classificar as submatrizes eO(n) tempo para mesclar a matriz inteira.
Quando resolvido,the time complexity will come to O(nLogn).
Isso vale para o pior, o médio e o melhor caso, pois sempre dividirá a matriz em duas e depois se fundirá.
A complexidade de espaço do algoritmo éO(n), pois estamos criando matrizes temporárias em cada chamada recursiva.
5. Conclusão
Neste tutorial rápido, vimos o funcionamento do algoritmo de classificação por mesclagem e como podemos implementá-lo em Java.
Todo o código de trabalho está disponívelover on GitHub.