0

Estructuras de Datos en C# 08: Algoritmos de Ordenación – Bubble Sort, Merge Sort, Quick Sort

Introducción a la clase

En esta clase exploraremos los principales algoritmos de ordenación, que permiten organizar datos en una secuencia específica. Compararemos sus ventajas, desventajas y su eficiencia en diferentes escenarios.

¿Qué obtendrás de esta clase?

  • Comprender la importancia de la ordenación en estructuras de datos.
  • Aprender e implementar Bubble Sort, Merge Sort y Quick Sort en C#.
  • Comparar la eficiencia de cada algoritmo utilizando Big O Notation.
  • Aplicar estos algoritmos en casos reales.

Bubble Sort

Bubble Sort es un algoritmo de ordenación simple pero ineficiente, que compara y intercambia elementos adyacentes hasta que toda la lista está ordenada.

Características de Bubble Sort

  • Comparaciones repetidas en pares de elementos.
  • Complejidad O(n²) en el peor caso.
  • No es recomendado para listas grandes debido a su baja eficiencia.

Implementación en C#

using System;

class Program
{
    static void BubbleSort(int[] arreglo)
    {
        int n = arreglo.Length;
        for (int i = 0; i < n - 1; i++)
        {
            for (int j = 0; j < n - i - 1; j++)
            {
                if (arreglo[j] > arreglo[j + 1])
                {
                    // Intercambiar elementos
                    int temp = arreglo[j];
                    arreglo[j] = arreglo[j + 1];
                    arreglo[j + 1] = temp;
                }
            }
        }
    }

    static void Main()
    {
        int[] numeros = { 64, 34, 25, 12, 22, 11, 90 };
        BubbleSort(numeros);
        Console.WriteLine("Array ordenado con Bubble Sort: " + string.Join(", ", numeros));
    }
}

Merge Sort

Merge Sort es un algoritmo de ordenación por división y conquista que divide el array en mitades, las ordena y luego las combina.

Características de Merge Sort

  • Divide el array en subarrays más pequeños.
  • Usa recursión para ordenar y fusionar los elementos.
  • Complejidad O(n log n) en todos los casos.

Implementación en C#

using System;

class Program
{
    static void Merge(int[] arreglo, int izquierda, int medio, int derecha)
    {
        int n1 = medio - izquierda + 1;
        int n2 = derecha - medio;

        int[] izquierdaArr = new int[n1];
        int[] derechaArr = new int[n2];

        for (int i = 0; i < n1; i++)
            izquierdaArr[i] = arreglo[izquierda + i];
        for (int j = 0; j < n2; j++)
            derechaArr[j] = arreglo[medio + 1 + j];

        int iL = 0, jR = 0, k = izquierda;

        while (iL < n1 && jR < n2)
        {
            if (izquierdaArr[iL] <= derechaArr[jR])
                arreglo[k++] = izquierdaArr[iL++];
            else
                arreglo[k++] = derechaArr[jR++];
        }

        while (iL < n1)
            arreglo[k++] = izquierdaArr[iL++];

        while (jR < n2)
            arreglo[k++] = derechaArr[jR++];
    }

    static void MergeSort(int[] arreglo, int izquierda, int derecha)
    {
        if (izquierda < derecha)
        {
            int medio = izquierda + (derecha - izquierda) / 2;
            MergeSort(arreglo, izquierda, medio);
            MergeSort(arreglo, medio + 1, derecha);
            Merge(arreglo, izquierda, medio, derecha);
        }
    }

    static void Main()
    {
        int[] numeros = { 64, 34, 25, 12, 22, 11, 90 };
        MergeSort(numeros, 0, numeros.Length - 1);
        Console.WriteLine("Array ordenado con Merge Sort: " + string.Join(", ", numeros));
    }
}

Quick Sort

Quick Sort selecciona un pivote, divide el array en elementos menores y mayores que el pivote y ordena recursivamente.

Características de Quick Sort

  • Usa particionamiento para dividir y conquistar.
  • Complejidad O(n log n) en promedio, pero O(n²) en el peor caso.
  • Más eficiente que Merge Sort en arreglos pequeños.

Implementación en C#

using System;

class Program
{
    static void QuickSort(int[] arreglo, int izquierda, int derecha)
    {
        if (izquierda < derecha)
        {
            int pivote = Particionar(arreglo, izquierda, derecha);
            QuickSort(arreglo, izquierda, pivote - 1);
            QuickSort(arreglo, pivote + 1, derecha);
        }
    }

    static int Particionar(int[] arreglo, int izquierda, int derecha)
    {
        int pivote = arreglo[derecha];
        int i = izquierda - 1;

        for (int j = izquierda; j < derecha; j++)
        {
            if (arreglo[j] < pivote)
            {
                i++;
                (arreglo[i], arreglo[j]) = (arreglo[j], arreglo[i]);
            }
        }

        (arreglo[i + 1], arreglo[derecha]) = (arreglo[derecha], arreglo[i + 1]);
        return i + 1;
    }

    static void Main()
    {
        int[] numeros = { 64, 34, 25, 12, 22, 11, 90 };
        QuickSort(numeros, 0, numeros.Length - 1);
        Console.WriteLine("Array ordenado con Quick Sort: " + string.Join(", ", numeros));
    }
}

Comparación entre los algoritmos de ordenación

AlgoritmoMejor casoPeor casoComplejidad promedioEstable
Bubble SortO(n)O(n²)O(n²)
Merge SortO(n log n)O(n log n)O(n log n)
Quick SortO(n log n)O(n²)O(n log n)No

Caso de uso real

Un sistema de comercio electrónico usa un algoritmo de ordenación para organizar productos según precio, popularidad o relevancia. Merge Sort y Quick Sort son las mejores opciones debido a su eficiencia.

Ejemplo en C#: Ordenación de productos por precio con Quick Sort

using System;

class Program
{
    static void QuickSort(decimal[] precios, int izquierda, int derecha)
    {
        if (izquierda < derecha)
        {
            int pivote = Particionar(precios, izquierda, derecha);
            QuickSort(precios, izquierda, pivote - 1);
            QuickSort(precios, pivote + 1, derecha);
        }
    }

    static int Particionar(decimal[] precios, int izquierda, int derecha)
    {
        decimal pivote = precios[derecha];
        int i = izquierda - 1;

        for (int j = izquierda; j < derecha; j++)
        {
            if (precios[j] < pivote)
            {
                i++;
                (precios[i], precios[j]) = (precios[j], precios[i]);
            }
        }

        (precios[i + 1], precios[derecha]) = (precios[derecha], precios[i + 1]);
        return i + 1;
    }

    static void Main()
    {
        decimal[] precios = { 299.99m, 149.99m, 79.99m, 499.99m, 199.99m };
        QuickSort(precios, 0, precios.Length - 1);
        Console.WriteLine("Productos ordenados por precio: " + string.Join(", ", precios));
    }
}

Próxima clase: Programación Dinámica y Algoritmos de Backtracking

En la siguiente clase exploraremos programación dinámica y backtracking, dos técnicas avanzadas utilizadas en problemas de optimización y generación de combinaciones.

Fernando Sonego

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *