Ordenamiento por mezcla

Harshit Jindal 12 octubre 2023
  1. Algoritmo de ordenamiento por mezcla
  2. Ejemplo de ordenamiento por mezcla
  3. Implementación del algoritmo Ordenamiento por mezcla
  4. Complejidad del algoritmo Ordenamiento por mezcla
Ordenamiento por mezcla

La Ordenamiento por mezcla es uno de los algoritmos de ordenación más populares y eficientes. Se basa en el principio del algoritmo divide y vencerás. Funciona dividiendo el array en dos mitades repetidamente hasta que obtenemos el array dividido en elementos individuales. Un elemento individual es un array ordenado en sí mismo. La ordenamiento por mezcla combina repetidamente estas pequeñas matrices ordenadas para producir submatrices ordenadas más grandes hasta que obtenemos una array final ordenada. Se utiliza mucho en aplicaciones de comercio electrónico.

Algoritmo de ordenamiento por mezcla

El método de ordenamiento por mezcla descendente comienza desde la parte superior con el array completo y procede hacia abajo a los elementos individuales con recursión.

Supongamos que tenemos un array sin ordenar A[] que contiene n elementos.

MergeSort()

  • Toma dos variables beg y end y almacena el índice del elemento inicial y del elemento final.
  • Encuentra el punto medio del array para dividirlo en dos mitades utilizando la fórmula mid =(beg+end)/2.
  • Divide el array en dos partes arr[beg, .... , mid] y arr[mid+1, .... , end].
  • Dividir repetidamente el array en subarrayas con elementos individuales utilizando la recursividad.
  • Llama a la función merge para empezar a construir el array ordenado.

Merge()

  • Inicializa el array auxiliar output para almacenar la salida ordenada.
  • Inicializa 3 punteros i, j y k.

    i apunta al principio de la primera subarray beg.

    j apunta al principio de la segunda subarray mid+1.

    k inicializado con beg mantiene el índice actual del array ordenado output.

  • Hasta que lleguemos al final de la subarray arr[beg, .... ,mid] o arr[mid+1, .... ,end], escogemos el valor más pequeño entre los elementos en el índice i &j y lo insertamos en output.
  • Escoge los elementos restantes y los inserta en output una vez que uno de los arrays se ha agotado.
  • Copiar output en arr[beg, ... , end].

Ejemplo de ordenamiento por mezcla

Supongamos que tenemos el array (5,3,4,2,1,6). Vamos a ordenarlo utilizando el algoritmo de ordenamiento por mezcla.

Acción (5,3,4,2,1,6) mergesort(0,5)
divide (5,3,4) (2,1,6) mergesort(0,2) mergesort(3,5)
divide (5,3) (4) (2,1) (6) mergesort(0,1) mergesort(2,2) mergesort(3,4) ordenamiento(5,5)
divide (5) (3) (4) (2) (1) (6) Matriz dividida en elementos individuales
merge (3,5) (4) (1,2) (6) merge(0,1) merge(2,2) merge(3,4) merge(5,5)
merge (3,4,5) (1,2,6) merge(0,2) merge(3,5)
merge (1,2,3,4,5,6) merge(0,5)

Obtenemos el array ordenado - (1 2 3 4 5 6)

Implementación del algoritmo Ordenamiento por mezcla

#include <iostream>
using namespace std;

void merge(int arr[], int beg, int mid, int end) {
  int output[end - beg + 1];
  int i = beg, j = mid + 1, k = 0;
  // add smaller of both elements to the output
  while (i <= mid && j <= end) {
    if (arr[i] <= arr[j]) {
      output[k] = arr[i];
      k += 1;
      i += 1;
    } else {
      output[k] = arr[j];
      k += 1;
      j += 1;
    }
  }
  // remaining elements from first array
  while (i <= mid) {
    output[k] = arr[i];
    k += 1;
    i += 1;
  }
  // remaining elements from the second array
  while (j <= end) {
    output[k] = arr[j];
    k += 1;
    j += 1;
  }
  // copy output to the original array
  for (i = beg; i <= end; i += 1) {
    arr[i] = output[i - beg];
  }
}

void mergeSort(int arr[], int beg, int end) {
  if (beg < end) {
    int mid = (beg + end) / 2;
    // divide and conquer
    mergeSort(arr, beg, mid);      // divide : first half
    mergeSort(arr, mid + 1, end);  // divide: second half
    merge(arr, beg, mid, end);     // conquer
  }
}
int main() {
  int n = 6;
  int arr[6] = {5, 3, 4, 2, 1, 6};
  cout << "Input array: ";
  for (int i = 0; i < n; i++) {
    cout << arr[i] << " ";
  }
  cout << "\n";
  mergeSort(arr, 0, n - 1);  // Sort elements in ascending order
  cout << "Output array: ";
  for (int i = 0; i < n; i++) {
    cout << arr[i] << " ";
  }
  cout << "\n";
}

Complejidad del algoritmo Ordenamiento por mezcla

Complejidad temporal

  • Caso medio

Merge Sort es un algoritmo recursivo. La siguiente relación de recurrencia da la expresión de la complejidad temporal de Merge sort.

T(n) = 2T(n/2) + θ(n)

El resultado de esta relación de recurrencia da T(n) = nLogn.También podemos verlo como un array de tamaño n que se divide en un máximo de Logn partes, y la fusión de cada parte toma O(n) tiempo.

Por tanto, la complejidad temporal es del orden de [Big Theta]: O(nLogn).

  • El peor caso

La complejidad temporal en el peor de los casos es del orden de [Big O]: O(nLogn).

  • El mejor caso

La complejidad temporal en el mejor de los casos es [Big Omega]: O(nLogn). Es la misma que la complejidad temporal del peor caso.

Complejidad espacial

La complejidad espacial del algoritmo Ordenamiento por mezcla es O(n) porque se necesita n espacio auxiliar para almacenar la subarray ordenada en la array auxiliar.

Harshit Jindal avatar Harshit Jindal avatar

Harshit Jindal has done his Bachelors in Computer Science Engineering(2021) from DTU. He has always been a problem solver and now turned that into his profession. Currently working at M365 Cloud Security team(Torus) on Cloud Security Services and Datacenter Buildout Automation.

LinkedIn

Artículo relacionado - Sort Algorithm