[C++] resolvió algunos algoritmos de clasificación comunes

Consejos: 1. Clasificación de burbuja 2. Clasificación de selección 3. Clasificación de inserción 4. Clasificación de colina 5. Clasificación rápida 6. Clasificación de combinación 7. Clasificación de montón 8. Clasificación de conteo 9. Clasificación de cubo 10. Clasificación de Radix

Tabla de contenido

1. Clasificación de burbujas

2. Clasificación de selección       

3. Clasificación por inserción

4. Clasificación de colinas

5. Clasificación rápida

6. Ordenar por fusión

7. Ordenar montones      

8. Clasificación de conteo

9. Clasificación de cubeta

10. Clasificación de raíz


1. Clasificación de burbujas

        Bubble sort es un algoritmo de clasificación simple que compara repetidamente dos elementos adyacentes e intercambia sus posiciones hasta que se ordena toda la matriz. La idea básica de la clasificación de burbujas es mover continuamente los elementos más grandes hacia atrás, al igual que las burbujas que flotan en el agua, de ahí el nombre de clasificación de burbujas.

Los siguientes son los pasos específicos de la clasificación de burbujas:

  1. A partir del primer elemento de la matriz, se comparan dos elementos adyacentes.
  2. Si el elemento anterior es mayor que el último, intercambie las posiciones de los dos elementos.
  3. La comparación y el intercambio de elementos adyacentes continúa hasta el último elemento.
  4. Repita los pasos anteriores, cada iteración mueve el elemento más grande al final de la matriz.
  5. Continúe con la siguiente iteración hasta que todos los elementos estén ordenados.

        La complejidad temporal de la ordenación de burbujas es O(n^2), donde n es la longitud de la matriz. Aunque la ordenación por burbuja no es el algoritmo de ordenación más eficiente, es simple de entender y aplicable en algunas situaciones.

//冒泡排序
void bubbleSort(int array[], int size) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (array[j] > array[j + 1]) {
                // 交换相邻元素的位置
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }
}

2. Clasificación de selección       

        La ordenación por selección también es un algoritmo de ordenación simple que selecciona el elemento más pequeño (o más grande) de la parte no ordenada cada vez y lo coloca al final de la parte ordenada. La idea básica de la clasificación por selección es encontrar el elemento más pequeño de la parte no clasificada e intercambiarlo con el final de la parte clasificada, construyendo gradualmente una secuencia ordenada.

Los siguientes son los pasos específicos del ordenamiento por selección:

  1. Comience con el primer elemento de la matriz, suponiendo que sea el elemento más pequeño.
  2. En la parte no clasificada, recorra para encontrar el elemento más pequeño y registre su índice.
  3. Intercambia el elemento más pequeño encontrado con el primer elemento de la sección no ordenada.
  4. Los pasos anteriores se repiten, cada iteración coloca el elemento más pequeño de la parte no ordenada al final de la parte ordenada.
  5. Continúe con la siguiente iteración hasta que todos los elementos estén ordenados.

        La complejidad temporal del ordenamiento por selección es O(n^2), donde n es la longitud de la matriz. Similar a la ordenación por burbuja, la ordenación por selección también es un algoritmo de ordenación simple pero menos eficiente.

//选择排序
void selectionSort(int array[], int size) {
    for (int i = 0; i < size - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < size; j++) {
            if (array[j] < array[minIndex]) {
                minIndex = j;
            }
        }
        // 交换最小元素和当前位置的元素
        int temp = array[i];
        array[i] = array[minIndex];
        array[minIndex] = temp;
    }
}

3. Clasificación por inserción

        La ordenación por inserción es un algoritmo de ordenación simple e intuitivo. Divide la matriz en partes ordenadas y no ordenadas, e inserta los elementos no ordenados en la posición correcta de la parte ordenada uno por uno. La idea básica de la ordenación por inserción es insertar un elemento en la posición correcta de la parte ordenada y expandir continuamente la longitud de la parte ordenada.

Los siguientes son los pasos específicos del ordenamiento por inserción:

  1. Comience con el segundo elemento de la matriz, que se considera el elemento que se va a insertar.
  2. Compare el elemento a insertar con los elementos de la parte clasificada para encontrar la posición adecuada.
  3. Mueve los elementos de la sección ordenada que son más grandes que el elemento que se va a insertar para dejar espacio para el elemento que se va a insertar.
  4. Inserte el elemento a insertar en la posición correcta en la parte ordenada.
  5. Continúe con la siguiente iteración, insertando el siguiente elemento sin ordenar en la parte ordenada.

        La complejidad temporal del ordenamiento por inserción es O(n^2), donde n es la longitud de la matriz. Aunque la clasificación por inserción no funciona tan bien como otros algoritmos de clasificación en el peor de los casos, en algunos casos puede funcionar mejor.

//插入排序
void insertionSort(int array[], int size) {
    for (int i = 1; i < size; i++) {
        int key = array[i];
        int j = i - 1;

        while (j >= 0 && array[j] > key) {
            array[j + 1] = array[j];
            j--;
        }

        array[j + 1] = key;
    }
}

4. Clasificación de colinas

        Hill sorting es una versión mejorada de un algoritmo de clasificación por inserción eficiente, que clasifica la matriz dividiéndola en varias subsecuencias, luego reduce gradualmente la longitud de las subsecuencias y finalmente completa la clasificación de toda la matriz. La característica de Hill sort es que puede realizar múltiples clasificaciones por inserción al principio, de modo que los elementos más pequeños se puedan mover rápidamente a la posición adecuada.

Los siguientes son los pasos específicos de la clasificación Hill:

  1. Elija una secuencia de incremento, generalmente la mitad de la longitud de la matriz, y divida la matriz en subsecuencias de acuerdo con la secuencia de incremento.
  2. Realice la ordenación por inserción en cada subsecuencia, es decir, realice la ordenación por inserción directa en los elementos de cada subsecuencia.
  3. Reduzca gradualmente la secuencia de incrementos y repita el paso 2 hasta que el incremento sea 1.
  4. Finalmente, se realiza una ordenación por inserción con un incremento de 1 para completar la ordenación de toda la matriz.

        La complejidad temporal del ordenamiento de Hill depende de la elección de la secuencia de incremento, pero en general es O(n^2). No obstante, la ordenación de Hill generalmente supera a la ordenación por inserción simple en la práctica.

//希尔排序
void shellSort(int array[], int size) {
    for (int gap = size / 2; gap > 0; gap /= 2) {
        for (int i = gap; i < size; i++) {
            int temp = array[i];
            int j;

            for (j = i; j >= gap && array[j - gap] > temp; j -= gap) {
                array[j] = array[j - gap];
            }

            array[j] = temp;
        }
    }
}

5. Clasificación rápida

        Quick sort es un algoritmo de clasificación eficiente que utiliza la idea de divide y vencerás. Divide la matriz en dos subarreglos seleccionando un elemento pivote, uno de los cuales tiene todos los elementos más pequeños que el elemento pivote y el otro subarreglo con todos los elementos mayores que el elemento pivote, y luego ordena recursivamente los dos subarreglos.

Los siguientes son los pasos específicos de clasificación rápida:

  1. Seleccione un elemento de referencia, que puede ser cualquier elemento de la matriz.
  2. Divide la matriz en dos subarreglos, uno con elementos más pequeños que el elemento pivote y el otro con elementos más grandes que el elemento pivote.
  3. Llame recursivamente a la ordenación rápida en los dos subconjuntos y detenga la recursividad cuando la longitud del subconjunto sea 1 o 0.
  4. Fusionar los subarreglos, es decir, fusionar el elemento pivote y los dos subarreglos ordenados.

        La complejidad temporal de ordenación rápida es O(nlogn), donde n es la longitud de la matriz. En general, es uno de los algoritmos de clasificación más rápidos en la práctica, pero puede funcionar mal en el peor de los casos.

//快速排序
int partition(int array[], int low, int high) {
    int pivot = array[high];
    int i = low - 1;

    for (int j = low; j < high; j++) {
        if (array[j] < pivot) {
            i++;
            // 交换元素
            int temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }
    }

    // 将基准元素放置在正确的位置
    int temp = array[i + 1];
    array[i + 1] = array[high];
    array[high] = temp;

    return i + 1;
}

void quickSort(int array[], int low, int high) {
    if (low < high) {
        int pivot = partition(array, low, high);
        quickSort(array, low, pivot - 1);
        quickSort(array, pivot + 1, high);
    }
}

6. Ordenar por fusión

        Merge sort es un algoritmo de clasificación eficiente que utiliza la idea de divide y vencerás. Divide la matriz en sub-matrices más pequeñas, luego ordena estas sub-matrices y finalmente las fusiona en una matriz ordenada. La clave para la ordenación por fusión es la operación de fusión, que combina dos subarreglos ordenados para obtener un arreglo ordenado.

Los siguientes son los pasos específicos del ordenamiento por fusión:

  1. Divide la matriz en subarreglos más pequeños hasta que los subarreglos tengan una longitud de 1.
  2. Para ordenar cada subarreglo, puede usar una llamada recursiva para mergesort.
  3. Combine dos subarreglos ordenados para obtener un arreglo ordenado más grande.
  4. La operación de fusión se repite hasta que todos los subarreglos se fusionan en una matriz ordenada completa.

        La complejidad temporal de la ordenación por fusión es O(nlogn), donde n es la longitud de la matriz. Es un algoritmo de clasificación estable y tiene un buen rendimiento cuando se trata de datos a gran escala.

//归并排序
void merge(int array[], int low, int mid, int high) {
    int n1 = mid - low + 1;
    int n2 = high - mid;

    int leftArray[n1];
    int rightArray[n2];

    for (int i = 0; i < n1; i++) {
        leftArray[i] = array[low + i];
    }

    for (int j = 0; j < n2; j++) {
        rightArray[j] = array[mid + 1 + j];
    }

    int i = 0;
    int j = 0;
    int k = low;

    while (i < n1 && j < n2) {
        if (leftArray[i] <= rightArray[j]) {
            array[k] = leftArray[i];
            i++;
        } else {
            array[k] = rightArray[j];
            j++;
        }
        k++;
    }

    while (i < n1) {
        array[k] = leftArray[i];
        i++;
        k++;
    }

    while (j < n2) {
        array[k] = rightArray[j];
        j++;
        k++;
    }
}

void mergeSort(int array[], int low, int high) {
    if (low < high) {
        int mid = low + (high - low) / 2;
        mergeSort(array, low, mid);
        mergeSort(array, mid + 1, high);
        merge(array, low, mid, high);
    }
}

7. Ordenar montones      

         La clasificación de montones utiliza la estructura de datos del montón para clasificar. Considera la matriz como un árbol binario completo e implementa la clasificación mediante la creación de un montón máximo o un montón mínimo. En el montón, el montón máximo garantiza que el valor de cada nodo sea mayor o igual que el valor de sus nodos secundarios, y el montón mínimo garantiza que el valor de cada nodo sea menor o igual que el valor de sus nodos secundarios. .

Los siguientes son los pasos específicos de la clasificación del montón:

  1. Cree la matriz en un montón máximo o mínimo.
  2. Intercambia el elemento superior del montón (elemento más grande o más pequeño) con el último elemento del montón.
  3. Reduce el tamaño del montón en 1 y cambia el tamaño del montón para que cumpla con las propiedades del montón.
  4. Repita los pasos 2 y 3 hasta que el tamaño del montón sea 1 y se complete la clasificación.

        La complejidad temporal de la ordenación del montón es O(nlogn), donde n es la longitud de la matriz. Es un algoritmo de clasificación inestable, pero tiene un buen rendimiento y es ampliamente utilizado en aplicaciones prácticas.

//堆排序
void heapify(int array[], int size, int root) {
    int largest = root;
    int left = 2 * root + 1;
    int right = 2 * root + 2;

    if (left < size && array[left] > array[largest]) {
        largest = left;
    }

    if (right < size && array[right] > array[largest]) {
        largest = right;
    }

    if (largest != root) {
        // 交换元素
        int temp = array[root];
        array[root] = array[largest];
        array[largest] = temp;

        heapify(array, size, largest);
    }
}

void heapSort(int array[], int size) {
    for (int i = size / 2 - 1; i >= 0; i--) {
        heapify(array, size, i);
    }

    for (int i = size - 1; i > 0; i--) {
        // 交换堆顶元素和当前位置元素
        int temp = array[0];
        array[0] = array[i];
        array[i] = temp;

        heapify(array, i, 0);
    }
}

8. Clasificación de conteo

        Counting sort es un algoritmo de clasificación no comparativo, adecuado para clasificar números enteros dentro de un cierto rango. Su idea básica es contar el número de ocurrencias de cada elemento y luego reorganizar la matriz según el orden del tamaño de los elementos.

Los siguientes son los pasos específicos del tipo de conteo:

  1. Encuentre el valor máximo de la matriz que se ordenará y determine el tamaño de la matriz de conteo.
  2. Cuente el número de ocurrencias de cada elemento en la matriz y guárdelo en la matriz de conteo.
  3. Calcule el valor acumulativo de cada elemento en la matriz de conteo para obtener la posición de cada elemento en la matriz ordenada.
  4. Cree una matriz temporal, coloque los elementos de la matriz para ordenarlos en la matriz temporal en secuencia de acuerdo con las posiciones en la matriz de conteo.
  5. Copia los elementos de la matriz temporal de nuevo a la matriz original.

        La complejidad temporal de la ordenación por conteo es O(n+k), donde n es la longitud de la matriz y k es el valor máximo de la matriz que se va a ordenar. El rendimiento del tipo de conteo es muy eficiente, pero debe cumplir ciertas condiciones.

//计数排序
void countingSort(int array[], int size) {
    int maxElement = array[0];
    for (int i = 1; i < size; i++) {
        if (array[i] > maxElement) {
            maxElement = array[i];
        }
    }

    int countArray[maxElement + 1] = {0};

    for (int i = 0; i < size; i++) {
        countArray[array[i]]++;
    }

    for (int i = 1; i <= maxElement; i++) {
        countArray[i] += countArray[i - 1];
    }

    int sortedArray[size];

    for (int i = size - 1; i >= 0; i--) {
        sortedArray[countArray[array[i]] - 1] = array[i];
        countArray[array[i]]--;
    }

    for (int i = 0; i < size; i++) {
        array[i] = sortedArray[i];
    }
}

9. Clasificación de cubeta

        La clasificación de cubos es un algoritmo de clasificación no comparativo, adecuado para clasificar números de punto flotante dentro de un cierto rango. Divide la matriz que se ordenará en varios cubos y asigna cada elemento al cubo correspondiente, luego ordena los elementos en cada cubo y finalmente saca los elementos en todos los cubos para obtener la matriz ordenada.

Los siguientes son los pasos específicos de la clasificación de cubetas:

  1. Determine el número de cubos, cada cubo representa un intervalo de rango.
  2. Recorra la matriz que se va a ordenar y coloque cada elemento en el cubo correspondiente.
  3. Para ordenar los elementos en cada cubo, puede usar algoritmos de ordenación como la ordenación por inserción y la ordenación rápida.
  4. De acuerdo con el orden de los cubos, los elementos de los cubos se extraen uno por uno para obtener una matriz ordenada.

        La complejidad temporal de la clasificación de cubos depende del número de cubos y del rendimiento del algoritmo de clasificación. En algunos casos, la clasificación de cubos puede lograr una complejidad de tiempo lineal.

//桶排序
#include <iostream>
#include <vector>
#include <algorithm>

void bucketSort(float array[], int size) {
    // 创建桶
    std::vector<float> buckets[size];

    // 将元素分配到对应的桶中
    for (int i = 0; i < size; i++) {
        int bucketIndex = size * array[i];
        buckets[bucketIndex].push_back(array[i]);
    }

    // 对每个桶中的元素进行排序
    for (int i = 0; i < size; i++) {
        std::sort(buckets[i].begin(), buckets[i].end());
    }

    // 合并所有的桶
    int index = 0;
    for (int i = 0; i < size; i++) {
        for (float element : buckets[i]) {
            array[index++] = element;
        }
    }
}

10. Clasificación de raíz

        Radix sort es un algoritmo de clasificación no comparativo que clasifica los números por cada dígito. La idea básica de la clasificación radix es ordenar los números secuencialmente desde el dígito más bajo (dígito de las unidades) hasta el dígito más alto (dígito alto), cada ronda se divide en cubos de acuerdo con el valor del dígito actual, y luego los números se reorganizan según el orden de los cubos. Después de múltiples rondas de clasificación, finalmente se obtiene una matriz ordenada.

Los siguientes son los pasos específicos de la clasificación radix:

  1. Determine el número de rondas de clasificación, en función del número máximo de dígitos.
  2. La operación de agrupamiento se realiza para cada ronda y el número se coloca en el contenedor correspondiente de acuerdo con el valor del bit actual.
  3. Reorganice los números en el orden de los cubos para obtener una nueva matriz.
  4. Repita los pasos anteriores hasta que se hayan recorrido todos los bits.

        La complejidad temporal de la clasificación de radix es O(d * (n + k)), donde n es la longitud de la matriz, d es el número máximo de dígitos y k es el número base. La clasificación Radix generalmente se usa para tratar con datos de tipo entero.

//基数排序
int getMax(int array[], int size) {
    int maxElement = array[0];
    for (int i = 1; i < size; i++) {
        if (array[i] > maxElement) {
            maxElement = array[i];
        }
    }
    return maxElement;
}

void countingSort(int array[], int size, int exp) {
    int output[size];
    int count[10] = {0};

    for (int i = 0; i < size; i++) {
        count[(array[i] / exp) % 10]++;
    }

    for (int i = 1; i < 10; i++) {
        count[i] += count[i - 1];
    }

    for (int i = size - 1; i >= 0; i--) {
        output[count[(array[i] / exp) % 10] - 1] = array[i];
        count[(array[i] / exp) % 10]--;
    }

    for (int i = 0; i < size; i++) {
        array[i] = output[i];
    }
}

void radixSort(int array[], int size) {
    int maxElement = getMax(array, size);

    for (int exp = 1; maxElement / exp > 0; exp *= 10) {
        countingSort(array, size, exp);
    }
}

Supongo que te gusta

Origin blog.csdn.net/crr411422/article/details/131194323
Recomendado
Clasificación