Mesclar classificação em Java

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:

image

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.