Ordenar arreglo en C# usando Quicksort - Algoritmo divide y vencerás

C# – Ordenar arreglo con Quicksort

En el post de hoy vamos a ver cómo ordenar un arreglo de C# (c sharp .NET) usando el algoritmo de Quicksort.

Vamos a hacer el algoritmo a mano, es decir, creando nuestras propias funciones para el ordenamiento de un array usando Quicksort o qs.

El algoritmo

Para ordenar un arreglo usando quicksort aplicamos el método de divide y vencerás. Tendremos dos apuntadores al arreglo, uno a la izquierda y uno a la derecha (o uno al inicio y otro al final).

El lugar en donde el algoritmo se divide es en el método de la partición. Este método debe indicar en qué índice del arreglo debemos hacer la división, es decir, en cuál índice separar el arreglo en 2.

Dentro del algoritmo de la partición vamos acercando los extremos mientras que cada elemento del arreglo esté ordenado. Si encontramos que hay un elemento que no está ordenado entonces intercambiamos los valores de los dos extremos.

La partición se detiene y regresa cuando hemos acercado los extremos de tal modo que la izquierda es mayor o igual a la derecha. En ese punto devolvemos el índice de la derecha, mismo que será usado para hacer otras particiones.

Al final vamos a ir dividiendo el arreglo en partes más pequeñas, y ordenando a las mismas. Pero el verdadero ordenamiento viene en la partición.

Yo sé que es mucha explicación y que puede ser confusa, pero verás que en el código se entiende de mejor manera.

Quicksort en C#

Entonces debemos implementar dos funciones en C sharp. La primera va a ser quien se encargue de ir dividiendo el arreglo eligiendo la partición, invocando a la función dentro de sí misma usando recursión.

La segunda función es la de la partición, misma que se va a encargar de ordenar el arreglo y devolver el índice en donde se quedó.

Partición

Veamos la función de C# que se encarga de ordenar la porción del arreglo:

static int particion(int[] arreglo, int izquierda, int derecha)
{
    int pivote = arreglo[izquierda];
    while (true)
    {
        /*
        Acercar los extremos hacia el centro mientras se encuentren elementos ordenados
         */
        while (arreglo[izquierda] < pivote)
        {
            izquierda++;
        }

        while (arreglo[derecha] > pivote)
        {
            derecha--;
        }
        // Si los extremos se cruzaron o superaron, entonces toda la porción del arreglo estaba ordenada
        if (izquierda >= derecha)
        {
            // Regresamos el índice para indicar hasta qué posición el arreglo está en orden
            return derecha;
        }
        else
        {
            // Si no estuvieron ordenados, vamos a hacer el intercambio
            int temporal = arreglo[izquierda];
            arreglo[izquierda] = arreglo[derecha];
            arreglo[derecha] = temporal;
            // Y acercamos en 1 los extremos
            derecha--; izquierda++;

        }
        // El while se repite hasta que izquierda >= derecha
    }
}

Como puedes notar, el código se explica por sí mismo apoyándose de los comentarios. Recuerda que el verdadero orden e intercambio está en la línea 27 en caso de que los elementos no hayan estado ordenados.

Función de qs

Y ahora que ya vimos la función de partición para elegir el pivote veamos la función quicksort para aplicar el algoritmo del mismo nombre en C#:

static void quicksort(int[] arreglo, int izquierda, int derecha)
{
    if (izquierda < derecha)
    {
        int indiceParticion = particion(arreglo, izquierda, derecha);
        quicksort(arreglo, izquierda, indiceParticion);
        quicksort(arreglo, indiceParticion + 1, derecha);
    }
}

Recuerda que aquí lo que se hace es ir dividiendo el arreglo. La primera parte es desde la izquierda hasta el pivote, y la segunda es desde el pivote + 1 hasta la derecha.

Conforme esta función se vaya invocando se va a ir partiendo al arreglo en trozos más pequeños.

Poniendo todo junto

Ordenar arreglo en C# usando Quicksort - Algoritmo divide y vencerás
Ordenar arreglo en C# usando Quicksort – Algoritmo divide y vencerás

Es momento de ver el código completo con un ejemplo. El mismo queda como se ve a continuación. Presta atención al modo de uso que está dentro del método Main.

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void quicksort(int[] arreglo, int izquierda, int derecha)
        {
            if (izquierda < derecha)
            {
                int indiceParticion = particion(arreglo, izquierda, derecha);
                quicksort(arreglo, izquierda, indiceParticion);
                quicksort(arreglo, indiceParticion + 1, derecha);
            }
        }
        static int particion(int[] arreglo, int izquierda, int derecha)
        {
            int pivote = arreglo[izquierda];
            while (true)
            {
                /*
                Acercar los extremos hacia el centro mientras se encuentren elementos ordenados
                 */
                while (arreglo[izquierda] < pivote)
                {
                    izquierda++;
                }

                while (arreglo[derecha] > pivote)
                {
                    derecha--;
                }
                // Si los extremos se cruzaron o superaron, entonces toda la porción del arreglo estaba ordenada
                if (izquierda >= derecha)
                {
                    // Regresamos el índice para indicar hasta qué posición el arreglo está en orden
                    return derecha;
                }
                else
                {
                    // Si no estuvieron ordenados, vamos a hacer el intercambio
                    int temporal = arreglo[izquierda];
                    arreglo[izquierda] = arreglo[derecha];
                    arreglo[derecha] = temporal;
                    // Y acercamos en 1 los extremos
                    derecha--; izquierda++;

                }
                // El while se repite hasta que izquierda >= derecha
            }
        }
        static void Main(string[] args)
        {
            /*
                https://parzibyte.me/blog
            */
            int[] arreglo = { 45, 12, 40, 34, 5, 10, 14, 900, 888, 700, 600, 4000, 1200 };
            Console.WriteLine("Antes de ordenar: ");
            foreach (int elemento in arreglo)
            {
                Console.Write(elemento);
                Console.Write(",");
            }
            // Ordenar. Recuerda que el arreglo original será modificado
            quicksort(arreglo, 0, arreglo.Length - 1);
            Console.WriteLine("\nDespués de ordenar: ");
            foreach (int elemento in arreglo)
            {
                Console.Write(elemento);
                Console.Write(",");
            }

        }

    }
}

Por cierto, en este caso he utilizado un arreglo de tipo entero pero puedes usar uno de cualquier tipo, por ejemplo uno de tipo string. Solo recuerda comparar correctamente los datos, ya que en el caso de las cadenas se usa CompareTo.

La salida ya la pudiste ver junto con el encabezado. Al final el arreglo estará ordenado usando el algoritmo quicksort.

Por aquí te dejo con más posts de C#.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

Dejar un comentario

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