Implementación y comparación de algoritmos de ordenamiento clásicos en C#

Se generan múltiples conjuntos de datos aleatorios para evaluar el rendmiiento de cuatro algoritmos de ordenamiento: burbuja, inserción, mezcla y rápido. Cada cnojunto se procesa con una copia independiente para garantiazr comparaciones justas.

public static void EjecutarPruebas()
{
    const int cantidadConjuntos = 10000;
    const int tamanoConjunto = 400;

    var listasOriginales = new List<int[]>(cantidadConjuntos);
    var copiasBurbuja = new List<int[]>(cantidadConjuntos);
    var copiasInsercion = new List<int[]>(cantidadConjuntos);
    var copiasMezcla = new List<int[]>(cantidadConjuntos);
    var copiasRapido = new List<int[]>(cantidadConjuntos);

    var cronometro = Stopwatch.StartNew();
    var generador = new Random();

    for (int idx = 0; idx < cantidadConjuntos; idx++)
    {
        var arreglo = new int[tamanoConjunto];
        for (int j = 0; j < tamanoConjunto; j++)
        {
            arreglo[j] = generador.Next(tamanoConjunto);
        }
        listasOriginales.Add(arreglo);
        copiasBurbuja.Add((int[])arreglo.Clone());
        copiasInsercion.Add((int[])arreglo.Clone());
        copiasMezcla.Add((int[])arreglo.Clone());
        copiasRapido.Add((int[])arreglo.Clone());
    }

    cronometro.Stop();
    Console.WriteLine($"Generación de datos: {cronometro.ElapsedMilliseconds} ms");

    cronometro.Restart();
    copiasBurbuja.ForEach(arr => OrdenarBurbuja(arr));
    cronometro.Stop();
    Console.WriteLine($"Ordenamiento burbuja: {cronometro.ElapsedMilliseconds} ms");

    cronometro.Restart();
    copiasInsercion.ForEach(arr => OrdenarPorInsercion(arr));
    cronometro.Stop();
    Console.WriteLine($"Ordenamiento por inserción: {cronometro.ElapsedMilliseconds} ms");

    cronometro.Restart();
    copiasMezcla.ForEach(arr => OrdenarPorMezcla(arr));
    cronometro.Stop();
    Console.WriteLine($"Ordenamiento por mezcla: {cronometro.ElapsedMilliseconds} ms");

    cronometro.Restart();
    copiasRapido.ForEach(arr => OrdenarRapido(arr));
    cronometro.Stop();
    Console.WriteLine($"Ordenamiento rápido: {cronometro.ElapsedMilliseconds} ms");
}

Ordenamiento por burbuja

public static void OrdenarBurbuja(int[] secuencia)
{
    if (secuencia.Length <= 1) return;

    for (int paso = 0; paso < secuencia.Length - 1; paso++)
    {
        bool intercambio = false;
        for (int i = 0; i < secuencia.Length - 1 - paso; i++)
        {
            if (secuencia[i] > secuencia[i + 1])
            {
                (secuencia[i], secuencia[i + 1]) = (secuencia[i + 1], secuencia[i]);
                intercambio = true;
            }
        }
        if (!intercambio) break;
    }
}

Ordenamiento por inserción

public static void OrdenarPorInsercion(int[] secuencia)
{
    if (secuencia.Length <= 1) return;

    for (int actual = 1; actual < secuencia.Length; actual++)
    {
        int valorActual = secuencia[actual];
        int posicion = actual - 1;

        while (posicion >= 0 && secuencia[posicion] > valorActual)
        {
            secuencia[posicion + 1] = secuencia[posicion];
            posicion--;
        }
        secuencia[posicion + 1] = valorActual;
    }
}

Ordenamiento por mezcla

public static void OrdenarPorMezcla(int[] secuencia)
{
    MezclarRecursivo(secuencia, 0, secuencia.Length - 1);
}

private static void MezclarRecursivo(int[] arr, int inicio, int fin)
{
    if (inicio >= fin) return;

    int mitad = inicio + (fin - inicio) / 2;
    MezclarRecursivo(arr, inicio, mitad);
    MezclarRecursivo(arr, mitad + 1, fin);
    CombinarSegmentos(arr, inicio, mitad, fin);
}

private static void CombinarSegmentos(int[] arr, int izq, int medio, int der)
{
    int lenIzq = medio - izq + 1;
    int lenDer = der - medio;
    var izquierda = new int[lenIzq];
    var derecha = new int[lenDer];

    Array.Copy(arr, izq, izquierda, 0, lenIzq);
    Array.Copy(arr, medio + 1, derecha, 0, lenDer);

    int i = 0, j = 0, k = izq;

    while (i < lenIzq && j < lenDer)
    {
        arr[k++] = izquierda[i] <= derecha[j] ? izquierda[i++] : derecha[j++];
    }

    while (i < lenIzq) arr[k++] = izquierda[i++];
    while (j < lenDer) arr[k++] = derecha[j++];
}

Ordenamiento rápido

public static void OrdenarRapido(int[] secuencia)
{
    ParticionarYOrdenar(secuencia, 0, secuencia.Length - 1);
}

private static void ParticionarYOrdenar(int[] arr, int bajo, int alto)
{
    if (bajo < alto)
    {
        int pivoteIdx = SeleccionarPivote(arr, bajo, alto);
        ParticionarYOrdenar(arr, bajo, pivoteIdx - 1);
        ParticionarYOrdenar(arr, pivoteIdx + 1, alto);
    }
}

private static int SeleccionarPivote(int[] arr, int inicio, int fin)
{
    int pivote = arr[fin];
    int indiceMenor = inicio;

    for (int actual = inicio; actual < fin; actual++)
    {
        if (arr[actual] < pivote)
        {
            (arr[indiceMenor], arr[actual]) = (arr[actual], arr[indiceMenor]);
            indiceMenor++;
        }
    }

    (arr[indiceMenor], arr[fin]) = (arr[fin], arr[indiceMenor]);
    return indiceMenor;
}

Etiquetas: C# algoritmos ordenamiento burbuja insercion

Publicado el 9-13 10:20