Voltar
Dividir e ConquistarIntermediário

Merge Sort

Divide o array ao meio recursivamente, então intercala as partes ordenadas — garantindo O(n log n) mesmo no pior caso.

Tempo:O(n log n)
Espaço:O(n)
01

Como Funciona

Passo a passo do algoritmo

1

Divida o array ao meio

Encontre o ponto médio e divida o array em duas metades. Continue dividindo recursivamente até ter subarrays de um único elemento.

meio = (baixo + alto) / 2 mergeSort(array, baixo, meio) mergeSort(array, meio+1, alto)
2

Caso base: array de um elemento

Um array com zero ou um elemento já está ordenado — é o caso base da recursão. A divisão para aqui.

se baixo >= alto: retorne
3

Intercale as duas metades ordenadas

Com as duas metades ordenadas, compare os menores elementos de cada uma. O menor vai para o array resultante. Repita até esgotar uma das metades.

enquanto i < esq.tamanho e j < dir.tamanho: se esq[i] ≤ dir[j]: resultado.add(esq[i++]) senão: resultado.add(dir[j++])
4

Copie os elementos restantes

Quando uma das metades se esgotar, copie todos os elementos restantes da outra metade para o resultado — eles já estão ordenados.

copiar restante de esq[] ou dir[] para resultado
5

Combine os resultados

O processo de divisão e intercalação acontece em todos os níveis da recursão. No topo, o array inteiro estará ordenado após a intercalação final.

// Complexidade: O(n log n) em todos os casos
02

Implementação

Código comentado em JavaScript e Python

function mergeSort(array) {
  // Caso base: array de 0 ou 1 elementos já está ordenado
  if (array.length <= 1) return array;

  // Divide o array ao meio
  const meio = Math.floor(array.length / 2);
  const esquerda = array.slice(0, meio);
  const direita = array.slice(meio);

  // Ordena recursivamente cada metade e intercala
  return intercalar(mergeSort(esquerda), mergeSort(direita));
}

function intercalar(esquerda, direita) {
  const resultado = [];
  let i = 0, j = 0;

  // Compara e intercala enquanto há elementos nas duas metades
  while (i < esquerda.length && j < direita.length) {
    if (esquerda[i] <= direita[j]) {
      resultado.push(esquerda[i]);
      i++;
    } else {
      resultado.push(direita[j]);
      j++;
    }
  }

  // Copia elementos restantes (já ordenados)
  return [...resultado, ...esquerda.slice(i), ...direita.slice(j)];
}

// Exemplo de uso
const arr = [38, 27, 43, 3, 9, 82, 10];
console.log(mergeSort(arr)); // [3, 9, 10, 27, 38, 43, 82]
03

Playground

Observe a divisão e intercalação do Merge Sort em cada nível

merge-sort — passo 1 de 28
Metade esquerda
Metade direita
Intercalando
Ordenado
38
[0]
27
[1]
43
[2]
3
[3]
9
[4]
82
[5]
10
[6]
Iniciando Merge Sort — dividindo o array em partes menores...
LentoRápido
04

Quando Usar

Cenários ideais para este algoritmo

Desempenho garantido

Quando você precisa de garantia de O(n log n) no pior caso — diferente do Quicksort que pode degradar para O(n²).

Ordenação externa (disco)

Ideal para ordenar dados maiores que a memória RAM — lê blocos do disco, ordena em memória e intercala sequencialmente.

Ordenação estável

Mantém a ordem relativa de elementos iguais — essencial quando a estabilidade importa (e.g., ordenar por múltiplos critérios).

Listas ligadas

Especialmente eficiente para listas ligadas — não precisa de acesso aleatório como outros algoritmos que usam índices.

05

Complexidade

Análise de desempenho por cenário

CenárioTempo
Melhor casoO(n log n)
Caso médioO(n log n)
Pior casoO(n log n)