Ordenar por categoría.

1. Introducción a la clasificación

Los algoritmos de clasificación se pueden dividir aproximadamente en dos tipos:
1. Clasificación comparativa, complejidad de tiempo O (nlogn) ~ O (n ^ 2), incluyen principalmente: clasificación de burbuja, clasificación de selección, clasificación de inserción, clasificación de fusión, clasificación de montón, espera de clasificación rápida .
2. Clasificación no comparativa, la complejidad del tiempo puede llegar a O (n), que incluye principalmente: clasificación de conteo, clasificación de radix, clasificación de cubos, etc.

inserte la descripción de la imagen aquí

2. Selección y clasificación

1. Método de clasificación de burbujas

Ideas de algoritmos:
1. Comparar elementos adyacentes. Si el primero es mayor que el segundo, intercámbialos
2. Haz lo mismo para cada par de elementos adyacentes, desde el primer par al principio hasta el último par al final, de modo que el último elemento sea el número más grande ;
3. Repita los pasos anteriores para todos los elementos excepto el último
4. Repita los pasos 1~3 hasta completar la clasificación.

inserte la descripción de la imagen aquí

código:

public class Bubble
 {
    
    
    public static void main(String[] args) {
    
    
        int array[] = {
    
    1,2,4,3,9,7,8,6};
        for( int i = 0;i < array.length;i++ ){
    
    
            for( int j = 0;j < array.length - 1;j++ ){
    
    
                if( array[j] > array[j+1] ){
    
    
                    int temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }
        for( int i = 0 ; i < array.length ; i++ ){
    
    
            System.out.print(array[i]+" ");
        }
    }
}

2. Clasificación de selección

Idea de algoritmo:
primero encuentre el elemento más pequeño (más grande) en la secuencia sin clasificar, guárdelo en la posición inicial de la secuencia ordenada, luego continúe buscando el elemento más pequeño (más grande) de los elementos sin clasificar restantes y luego colóquelo al final de la secuencia ordenada. Y así sucesivamente hasta que todos los elementos estén ordenados.

inserte la descripción de la imagen aquí

código:

public class Select {
    
    
    public static void main(String[] args) {
    
    
        int minIndex = 0;
        int temp = 0;
        int array[] = {
    
    1,2,4,3,9,7,8,6};
        for(int i = 0;i < array.length;i++){
    
    
            minIndex = i;                  //先假设最开始的元素为最小的元素
            for( int j = i + 1;j < array.length;j++ ){
    
    
                if( array[j] < array[minIndex] ){
    
      // 寻找最小的数
                     minIndex = j;                 // 将最小数的索引保存
                }
            }
            temp = array[minIndex];    //将此轮的最小元素和最开始的元素交换
            array[minIndex] = array[i];
            array[i] = temp;
        }
        for( int i = 0;i < array.length;i++ ){
    
    
            System.out.print(array[i]+" ");
        }
    }
}

3. Clasificación por inserción

Ideas de algoritmos:
1. A partir del primer elemento, se puede considerar que el elemento está ordenado
2. Extraiga el siguiente elemento y escanee de atrás hacia adelante en la secuencia de elementos ordenados 3.
Si el elemento (ordenado) está mayor que Nuevo elemento, mueva el elemento a la siguiente posición
4. Repita el paso 3 hasta que se encuentre la posición donde el elemento ordenado es menor o igual que el nuevo elemento 5.
Inserte el nuevo elemento en la posición
6. Repita pasos 2~5.

inserte la descripción de la imagen aquí

código:

public class Insert {
    
    
    public static void main(String[] args) {
    
    
        int array[] = {
    
    1,2,4,3,9,7,8,6};
        int index = 0;
        int current = 0;
        for (int i = 1; i < array.length; i++) {
    
    
            index = i - 1;        //左边的排是排好序的
            current = array[i];   //表示当前取到的扑克牌
            while (index >= 0 && array[index] > current) {
    
       //如果左边的排比取到的排大则右移
                array[index + 1] = array[index];
                index--;
            }
            array[index + 1] = current; //直到该手牌比抓到的牌小(或二者相等),将抓到的牌插入到该手牌右边
        }

        for( int i = 0 ; i < array.length ; i++ ){
    
    
            System.out.print(array[i]+" ");
        }
    }
}

4. Ordenar por fusión

Idea de algoritmo:
Este algoritmo es una aplicación muy típica de Divide and Conquer. Combine las subsecuencias ordenadas para obtener una secuencia completamente ordenada; es decir, primero haga cada subsecuencia en orden y luego haga los segmentos de subsecuencia en orden. La combinación de dos listas ordenadas en una sola lista ordenada se denomina combinación bidireccional.
1. Dividir la secuencia de entrada de longitud n en dos subsecuencias de longitud n/2
2. Combinar y ordenar las dos subsecuencias respectivamente
3. Combinar las dos subsecuencias ordenadas en una secuencia final ordenada.

inserte la descripción de la imagen aquí

código:

/*
    k表示最终i和j比较之后最终需要放的位置
    i和j用来表示当前需要考虑的元素
    left表示最左边的元素
    right表示最右边的元素
    middle表示中间位置元素,放在第一个已经排好序的数组的最后一个位置
*/
public class Merging {
    
    
    /*******************测试************************/
    public static void main(String[] args) {
    
    
          int[] nums = {
    
     2, 7, 8, 3, 1, 6, 9, 0, 5, 4 , 9 , 19 ,12,16,14,12,22,33 };

          mergeSort(nums , 0 , nums.length - 1 );
          System.out.println(Arrays.toString(nums));
    }
    /********************算法************************/
    /*
        arr:要处理的数组
        l:开始位置
        r:结束位置
        递归对arr[ l ... r ]范围的元素进行排序
     */
    private static void mergeSort(int[] arr,int left,int right){
    
    
        if( right - left <= 10 ){
    
       //当数据很少的时候使用插入排序算法
            ChaRuPaiXu.ChaRuPaiXuFa2( arr , left ,right);
            return;
        }
        int middle = ( left + right ) / 2;  //计算中点位置
        mergeSort( arr , left , middle );   //不断地对数组的左半边进行对边分
        mergeSort( arr , middle+1 , right );   //不断地对数组的右半边进行对半分
        if( arr[middle] > arr[middle+1] )//当左边最大的元素都比右边最小的元素还小的时候就不用归并了
            merge( arr , left , middle , right );  //最后将已经分好的数组进行归并
    }
    //将arr[ l... mid ]和arr[ mid ... r ]两部分进行归并
    /*
        |2, 7, 8, 3, 1  |  6, 9, 0, 5, 4|
     */
    private static void merge(int[] arr, int left, int mid, int right) {
    
    
        int arr1[] = new int[ right - left + 1 ];   //定义临时数组
        for( int i = left ; i <= right ; i++ )    //将数组的元素全部复制到新建的临时数组中
            arr1[ i - left ] = arr[ i ];
        int i = left;
        int j = mid + 1;     //定义两个索引
        for( int k = left;k <= right ; k++){
    
    
             if( i > mid )   //如果左边都比较完了
             {
    
    
                 arr[ k ] = arr1[ j - left ];   //直接将右边的元素都放进去
                 j++;
             }
             else if( j > right ){
    
       //右边都比较完了
                 arr[ k ] = arr1 [i - left ];   //直接将左边的元素放进去
                 i++;
             }
             else if( arr1[ i-left ] < arr1[ j-left ] ){
    
    
                 arr[ k ] = arr1[ i - left];
                 i++;
             }
            else
             {
    
    
                 arr[ k ] = arr1[ j - left];
                 j++;
             }
        }
    }
}

5. Clasificación rápida

Idea de algoritmo:
separe los registros que se van a clasificar en dos partes independientes mediante la clasificación de un solo paso, y las palabras clave de una parte de los registros son más pequeñas que las de la otra parte, entonces las dos partes de los registros se pueden clasificar por separado para lograr el orden de toda la secuencia secuencia.
Quicksort utiliza un método divide y vencerás para dividir una cadena (lista) en dos subcadenas (sublistas).
1. Elija un elemento de la secuencia, llamado "pivot" (pivote),
2. Reordene la secuencia, todos los elementos que son más pequeños que el valor del pivote se colocan delante del pivote, y todos los elementos que son más grandes que el valor del pivote se colocan detrás del pivote (el mismo número puede ir a cualquier lado). Después de que esta partición sale, el punto de referencia está en el medio de la secuencia. Esto se denomina operación de partición:
3. Ordenar de forma recursiva (recursiva) los subconjuntos de elementos menores que el valor de referencia y los subconjuntos de elementos mayores que el valor de referencia.

inserte la descripción de la imagen aquí

código:

public class Quick {
    
    
    public static void main(String[] args){
    
    
        int array[] = {
    
    1,2,4,3,9,7,8,6};

        quickSort(array,0,array.length-1);
        for( int i = 0 ; i < array.length ; i++ ){
    
    
            System.out.print(array[i]+" ");
        }
    }
    private static void quickSort(int[] arr,int l,int r){
    
    
        if( l >= r )  return;
        int p = partition(arr,l,r);    //找到中间位置
        quickSort(arr,l,p-1);
        quickSort(arr,p+1,r);
    }
    private static int partition(int[] arr,int l,int r){
    
    
        int v = arr[l];   //取出第一个元素
        int j = l;        //j表示小于第一个元素和大于第一个元素的分界点
        for( int i = l + 1;i <= r;i++ ){
    
    
            //将所有小于第一个元素的值的元素全部都放到它的左边
            if( arr[i] < v ){
    
         //如果当前元素小于v,则交换
                swap(arr,i,j+1);
                j++;
            }
        }
        swap(arr,l,j);  //将第一个元素和中间的元素进行交换
        return j;
    }
}

6. Ordenar montones

Ideas de algoritmos:
Heapsort (Heapsort) se refiere a un algoritmo de clasificación diseñado utilizando la estructura de datos del montón. El apilamiento es una estructura que se aproxima a un árbol binario completo y, al mismo tiempo, satisface la naturaleza del apilamiento: es decir, el valor clave o el índice de un nodo secundario siempre es más pequeño (o más grande) que su nodo principal.

inserte la descripción de la imagen aquí

El montón máximo requiere que los elementos de un nodo no sean más pequeños que sus hijos, y el montón mínimo requiere que los elementos de un nodo no sean más grandes que sus hijos izquierdo y derecho, por lo que el elemento
del nodo raíz en el montón máximo debe ser el valor máximo en el montón.

public class Heap {
    
    
    public static void main(String[] args) {
    
    
        int A[]={
    
    49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
        HeapSort(A, A.length);
        System.out.println(Arrays.toString(A));
    }
public static void Swap(int A[], int i, int j)
{
    
    
    int temp = A[i];
    A[i] = A[j];
    A[j] = temp;
}
public static void Heapify(int A[], int i, int size)  // 从A[i]向下进行堆调整
{
    
    
    int left_child = 2 * i + 1;         // 左孩子索引
    int right_child = 2 * i + 2;        // 右孩子索引
    int max = i;                        // 选出当前结点与其左右孩子三者之中的最大值
    if (left_child < size && A[left_child] > A[max])
        max = left_child;
    if (right_child < size && A[right_child] > A[max])
        max = right_child;
    if (max != i)
    {
    
    
        Swap(A, i, max);                // 把当前结点和它的最大(直接)子节点进行交换
        Heapify(A, max, size);          // 递归调用,继续从当前结点向下进行堆调整
    }
}
public static int BuildHeap(int A[], int n)           // 建堆,时间复杂度O(n)
{
    
    
    int heap_size = n;
    for (int i = heap_size / 2 - 1; i >= 0; i--) // 从每一个非叶结点开始向下进行堆调整
        Heapify(A, i, heap_size);
    return heap_size;
}
public static void HeapSort(int A[], int n)
{
    
    
    int heap_size = BuildHeap(A, n);    // 建立一个最大堆
    while (heap_size > 1)   // 堆(无序区)元素个数大于1,未完成排序
    {
    
    
        // 将堆顶元素与堆的最后一个元素互换,并从堆中去掉最后一个元素
        // 此处交换操作很有可能把后面元素的稳定性打乱,所以堆排序是不稳定的排序算法
        Swap(A, 0, --heap_size);
        Heapify(A, 0, heap_size);     // 从新的堆顶元素开始向下进行堆调整,时间复杂度O(logn)
    }
}
}

7. Clasificación de colinas

Idea de algoritmo:
1. Seleccionar una secuencia incremental t1, t2, ..., tk, donde ti>tj, tk=1
2. Según el número k de secuencias incrementales, ordenar la secuencia por k veces
3. Para cada tiempo de clasificación. De acuerdo con el correspondiente incremento ti, la columna a clasificar se divide en varias subsecuencias de longitud my se realiza una clasificación por inserción directa en cada subtabla. Solo cuando el factor de incremento es 1, la secuencia completa se trata como una tabla y la longitud de la tabla es la longitud de la secuencia completa.

inserte la descripción de la imagen aquí

Knuth propuso la secuencia h de uso común. La secuencia comienza en 1 y se genera mediante la siguiente fórmula:
h = 3 * h +1 A su vez, el programa necesita calcular la secuencia h a la inversa, y h = ( h - 1 ) /
Se debe usar el código 3 :

public class Shell {
    
    
    public static void main(String[] args) {
    
    
        int array[] = {
    
    1,2,4,3,9,7,8,6};
        int h = 0;
        int length = array.length;
        while( h <= length ){
    
        //计算首次步长
            h = 3 * h + 1;
        }
        while( h >= 1 ){
    
    
            for( int i = h;i < length;i++ ){
    
    
                int j = i - h;         //左边的一个元素
                int get = array[i];    //当前元素
                while( j >= 0 && array[j] > get ){
    
       //左边的比当前大,则左边的往右边挪动
                    array[j+h] = array[j];
                    j = j - h;
                }
                array[j + h] = get;  //挪动完了之后把当前元素放进去
            }
            h = ( h - 1 ) / 3;  
        }
        for( int i = 0 ; i < array.length ; i++ ){
    
    
            System.out.print(array[i]+" ");
        }
    }
}

Supongo que te gusta

Origin blog.csdn.net/weixin_48006490/article/details/126500916
Recomendado
Clasificación