Conceptos básicos del algoritmo de clasificación + clasificación de burbujas + pequeña optimización de clasificación de burbujas

Algoritmo de clasificación

Categorías ordenadas:

1) Clasificación interna: se refiere a cargar todos los datos que deben procesarse en la memoria interna ** (memoria) ** para clasificar.
2) Método de clasificación externo: la cantidad de datos es demasiado grande para cargarlos todos en la memoria y es necesario clasificarlos con la ayuda del almacenamiento externo.

Inserte la descripción de la imagen aquí

complejidad del tiempo


Este método de posestadísticas es factible, pero hay dos problemas: uno es evaluar el rendimiento del algoritmo diseñado, es necesario ejecutar realmente el programa; el otro es que las estadísticas del tiempo obtenidas dependen del hardware de la computadora, software, etc. Los factores ambientales, de esta manera, deben ejecutarse en la misma computadora en el mismo estado, para poder comparar ese algoritmo más rápidamente .

El método de preestimación
juzga qué algoritmo es mejor analizando la complejidad temporal de un algoritmo.

Frecuencia de tiempo

Frecuencia de tiempo: el tiempo empleado por un algoritmo es proporcional al número de ejecuciones de la declaración en el algoritmo. Cuanto mayor es el número de ejecuciones de la declaración en el algoritmo, más tiempo toma. El número de ejecuciones de declaraciones en un algoritmo se denomina frecuencia de declaraciones o frecuencia de tiempo. Denotado como T (n).

P.ej:

int total = 0;
int end = 100;
//使用for循环计算
for(int i=1;i<=end;i++)			
{
    
    
    total += i;
}
T(n) = n+1;		//n代表程序规模,在这里也就是循环的次数100次 101
//直接计算
total = (1+end)*end/2;
T(n) = 1

En conclusión:

El término constante generalmente se ignora

2n + 20 y 2n a medida que n aumenta, la curva de ejecución es infinitamente cercana, 20 se puede ignorar
3n + 10 y 3n a medida que n aumenta, la curva de ejecución es infinitamente cercana, 10 se puede ignorar

Los términos de orden inferior generalmente se ignoran

2n 2 + 3n + 10 y 2n 2 A medida que n se vuelve más grande, la curva de ejecución es infinitamente cercana y se puede ignorar. 3n + 10
n 2 + 5n + 20 y n 2 A medida que n se vuelve más grande, la curva de ejecución es infinitamente cercana y 5n + 20 se pueden ignorar.

¿Qué hay de ignorar el coeficiente? Generalmente, cuando el número de ocurrencias difiere demasiado, el coeficiente puede ignorarse.

Complejidad del tiempo computacional

En general, el número de ejecuciones repetidas del enunciado de operación básica en el algoritmo es una función de la escala del problema n, representada por n). Si hay una determinada función auxiliar f (n), cuando n tiende a infinito, T El límite El valor de (m) / f (n) es una constante que no es igual a cero, y se dice que f (n) es una función del mismo orden de magnitud de T (n). Denotarlo como T (n) = 0 (f (n)), y llamar O (f (n)) la complejidad de tiempo asintótica del algoritmo, conocida como complejidad de tiempo. Por ejemplo, nuestro anterior T (n) = n + 1, suponga que f (n) = n, T (n) / f (n) está infinitamente cerca de 1, entonces f (n) es la función auxiliar

T (n) es diferente, pero la complejidad del tiempo puede ser la misma. Por ejemplo: T (n) = n ^ 2 + 7n + 6 y T (n) 3n 2 + 2n + 2 tienen diferentes T (n), pero la complejidad del tiempo es la misma, ambos son 0 (n 2).

Utilice la constante 1 para reemplazar todas las constantes de suma en el tiempo de ejecución T (n) = n ^ 2 + 7n + 6 ===> T (n) = n ^ 2 + 7n + 1 En la
función de frecuencia de ejecución modificada, solo se retiene el valor más alto Término de orden T (n) = n ^ 2 + 7n + 1 ===> T (n) = n ^ 2
Quite el coeficiente del término de orden más alto T (n) = n ^ 2 = T ( n) = n ^ 2 => O (n) = n ^ 2

Complejidad de tiempo común

1) Orden constante 0 (1)
2) Orden logarítmico 0 (log2n)
3) Orden lineal 0 (n)
4) Orden logarítmico lineal 0 (nlog2n)
5) Orden cuadrado 0 (n ^ 2)
6) Orden cúbico 0 (n ^ 3)
7) k-ésimo orden 0 (n ^ k)
8) Orden exponencial 0 (2 ^ n)

La complejidad temporal de los algoritmos comunes de pequeños a grandes es: 0 (1) <0 (log2n) <o (n) <o (nlog2n) <0 (n 2) <0 (n 3)) <0 (n ^ k ) <0 (2 ^ n) , a medida que la escala del problema n continúa aumentando, la complejidad de tiempo mencionada anteriormente continúa aumentando y la eficiencia de ejecución del algoritmo es menor

Así que intentamos evitar el orden exponencial tanto como sea posible.

ejemplo

Orden constante O (1)

int i = 1; 
int j = 1;
++1;
++j;
int m = i + j;	
上述代码在执行的时候,它消耗的时候并丕随着某个变量的增长而增长,那么无论这类代码有多长,即使有几万几十万行,都可以用0(1)采表示它的时间复杂度。

Orden logarítmico 0 (log2n)

int i = 1;
while(i<n){
    
    
    i = i * 2;
}

Explicación: En el ciclo while, i se multiplica cada vez por 2. Después de la multiplicación, i se acerca cada vez más a n. Suponiendo que después del ciclo x veces, i es mayor que 2, el ciclo sale en este momento, es decir, la potencia x de 2 es igual an, entonces x = log2n, es decir, el código termina después el bucle log2n veces. Por lo tanto, la complejidad de tiempo de este código es: O (log2n). El tiempo 2 de O (log2n) cambia según el código, i = i * 3, luego 0 (log; n)

Para un ejemplo simple, el código anterior n = 1024, ¿cuántas veces se ejecuta el programa? Tiempos = log2n

¿Qué pasa con n = 9, i = i * 3? Es el número igual a log3 9 = 2 veces, la primera vez es 1X3, la segunda vez es 3X3

Orden lineal 0 (n)

for(int i=1;i<n;i++){
    
    
    j = 1;
    j++;
}

Explicación: Este código, el código en el bucle for se ejecutará n veces, por lo que el tiempo que consume varía con el cambio de n, por lo que este tipo de código puede usar 0 (n) para representar su complejidad de tiempo.

Orden logarítmico lineal 0 (nlog2n)

for(int m=1;m<n;m++){
    
    
   i = 1;
    while(i<n){
    
    
        i = i * 2;
    }
}

¿No es esto solo una combinación, un tiempo adentro para

Orden cuadrado 0 (n ^ 2)

Como sugiere el nombre, es un bucle for doble.

for(int i=1;i<n;i++){
    
    
    for(int i=1;i<n;i++){
    
    
    	j = i;
        j++
	}
}

Por analogía, la otra complejidad del tiempo se revela una a una

Complejidad de tiempo promedio y peor complejidad de tiempo,

La complejidad de tiempo promedio se refiere al tiempo de ejecución del algoritmo cuando todas las instancias de entrada posibles aparecen con la misma probabilidad.

La complejidad de tiempo del peor de los casos se denomina complejidad de tiempo del peor. La complejidad de tiempo discutida en general es la complejidad de tiempo del peor de los casos
. ** La razón de esto es: ** La complejidad del tiempo en el peor de los casos es el límite del tiempo de ejecución del algoritmo en cualquier instancia de entrada, lo que garantiza que el tiempo de ejecución del algoritmo no será más largo que en el peor de los casos.

Método de clasificación Tiempo promedio Peor de los casos estabilidad Espacio extra Observaciones
burbuja En 2) En 2) estable O (1) n horas es mejor
intercambio En 2) En 2) Inestable O (1) n horas es mejor
Seleccione En 2) En 2) Inestable O (1) n horas es mejor
insertar En 2) En 2) estable O (1) Mejor cuando la mayoría de ellos están ordenados
Base O (log RB) O (log RB) estable Sobre) B es un número verdadero (0-9), R es una base (diezcientos)
Cáscara O (nlogn) O (n ^ s) 1 <s <2 Inestable O (1) s es el grupo seleccionado
rápido O (nlogn) O (n ^ 2) Inestable O (nlogn) n es mejor cuando es grande
Unir O (nlogn) O (nlogn) estable O (1) n es mejor cuando es grande
montón O (nlogn) O (nlogn) Inestable O (1) n es mejor cuando es grande

Complejidad espacial

De manera similar a la teoría de la complejidad del tiempo de Wang, la complejidad espacial de un algoritmo se define como el espacio de almacenamiento consumido por el algoritmo, que también es una función del tamaño del problema n.

La complejidad espacial (complejidad espacial) es una medida de la cantidad de espacio de almacenamiento que un algoritmo ocupa temporalmente durante su funcionamiento. El número de unidades de trabajo temporal que deben ocupar algunos algoritmos está relacionado con la escala n del problema. Aumenta con el aumento de n. Cuando n es mayor, ocupará más unidades de almacenamiento, como los algoritmos de ordenación rápida y ordenación combinada Este es el caso

Al realizar un análisis de algoritmos, la discusión principal es la complejidad del tiempo. Desde el punto de vista de la experiencia del usuario, la velocidad de ejecución del programa es más importante. Algunos productos de almacenamiento en caché (redis, memcache) y algoritmos (clasificación de cardinalidad) utilizan esencialmente espacio para el tiempo .

Ordenamiento de burbuja

introducción básica

La idea básica de la clasificación de burbujas es:

Por orden de secuencia de adelante hacia atrás (desde el índice más pequeño del elemento), comparando el valor de los elementos adyacentes secuencialmente, en orden inverso si se encuentra, entonces el interruptor, de modo que el valor del elemento sea gradualmente mayor hacia la parte posterior de el pasado , como agua Las burbujas de abajo se elevan gradualmente hacia arriba

Cuál es el orden inverso: es la estrategia que estableces, le dejas crecer de pequeño a grande, el primero grande es el orden inverso

Debido a que cada elemento se acerca constantemente a su posición durante el proceso de clasificación, si no hay intercambio en una comparación, la secuencia está en orden, por lo que se debe colocar una bandera durante el proceso de clasificación para determinar si el elemento ha sido intercambiado. Reduciendo así las comparaciones innecesarias. Se optimizará más tarde.

Diagrama de clasificación de burbujas

img

regla:

El número total de veces que se realizará es el tamaño de la matriz n-1 veces

El número de clases en cada pasada está disminuyendo gradualmente.

Si no hay intercambio en un determinado proceso de clasificación, podemos finalizar la clasificación antes (optimización)

Código

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/20 21:54
 * @Description TODO
 * @pojectname 冒泡排序
 */
public class BubbleSort {
    
    
    public static void main(String[] args) {
    
    
        //给出我们需要排序的数组
        int[] array = {
    
    3,9,-1,10,-2};
        int temp = 0;//临时变量,交换的时候用
        for (int i = 0; i <array.length-1 ; i++) {
    
    
            for (int j = 0; j < array.length-1-i ; j++) {
    
    
                //如果前面的数比后面数大,交换
            if (array[j] > array[j+1]){
    
    
                temp = array[j];
                array[j] = array[j+1];
                array[j+1] = temp;
             }
            }
            System.out.println("第"+(i+1)+"次排序后的数组");
            System.out.println(Arrays.toString(array));
        }


//        //第一次排序,就是为了把最大的数,排在最后
//        int temp = 0;//临时变量,交换的时候用
//        for (int j=0;j<array.length-1;j++){
    
    
//            //如果前面的数比后面数大,交换
//            if (array[j] > array[j+1]){
    
    
//                temp = array[j];
//                array[j] = array[j+1];
//                array[j+1] = temp;
//            }
//        }
//        System.out.println("第一次排序后的数组");
//        System.out.println(Arrays.toString(array));
//
//        //第二趟排序,把第二大的数排在倒数第二位
//        for (int j=0;j<array.length-1-1;j++){
    
    
//            //如果前面的数比后面数大,交换
//            if (array[j] > array[j+1]){
    
    
//                temp = array[j];
//                array[j] = array[j+1];
//                array[j+1] = temp;
//            }
//        }
//        System.out.println("第二次排序后的数组");
//        System.out.println(Arrays.toString(array));
//
//        //第三趟排序,把第三大的数排在倒数第三位
//        for (int j=0;j<array.length-1-1-1;j++){
    
    
//            //如果前面的数比后面数大,交换
//            if (array[j] > array[j+1]){
    
    
//                temp = array[j];
//                array[j] = array[j+1];
//                array[j+1] = temp;
//            }
//        }
//        System.out.println("第三次排序后的数组");
//        System.out.println(Arrays.toString(array));
//        //第四趟排序,把第三大的数排在倒数第四位
//        for (int j=0;j<array.length-1-3;j++){
    
    
//            //如果前面的数比后面数大,交换
//            if (array[j] > array[j+1]){
    
    
//                temp = array[j];
//                array[j] = array[j+1];
//                array[j+1] = temp;
//            }
//        }
//        System.out.println("第四次排序后的数组");
//        System.out.println(Arrays.toString(array));
    }
}

El comentario que hicimos es para entender. No es difícil para nosotros encontrar las reglas. La primera vez que lo ordenamos es array.length-1-0, y la segunda vez es array.lenth-1-1. Desde entonces , no es difícil para nosotros encontrar La operación de bucle for es la misma, pero el número de bucles es diferente cada vez, entonces podemos aplicar un bucle for igual a la capa exterior, y el bucle for interno controla el número diferente de bucles ordena cada vez

Después de la optimización

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/20 21:54
 * @Description TODO
 * @pojectname 冒泡排序
 */
public class BubbleSort {
    
    
    public static void main(String[] args) {
    
    
        //给出我们需要排序的数组
        int[] array = {
    
    3,9,-1,10,20};
        bubbleSort(array);
        System.out.println("排序后的数组");
        System.out.println(Arrays.toString(array));
    }
    //将前面的排序算法疯转成一个方法
    public static void bubbleSort(int[] array){
    
    
        int temp = 0;//临时变量,交换的时候用
        boolean flag = false;//表示是否进行过交换
        for (int i = 0; i <array.length-1 ; i++) {
    
    
            for (int j = 0; j < array.length-1-i ; j++) {
    
    
                //如果前面的数比后面数大,交换
                if (array[j] > array[j+1]){
    
    
                    flag = true;//说明做出了交换,我不能终止排序
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
            if (flag == false){
    
    //一次循环,没有任何交换
                break;
            }
            else {
    
    
                flag = false;//重置我们的flag,下次交换还得用呢
            }
        }
    }
}

La introducción de nuestra bandera es para optimizar la cantidad de clases, algunos datos son especiales, nuestra bandera puede terminar de clasificarse antes

Lo interesante es que la matriz es muy rápida cuando int [8] es muy rápida, pero tarda más de 20 segundos cuando int [80000]

Supongo que te gusta

Origin blog.csdn.net/qq_22155255/article/details/111464074
Recomendado
Clasificación