[Conceptos básicos de algoritmos (1)] Comprender la complejidad del tiempo y los algoritmos de clasificación más utilizados

1 Comprender la complejidad del tiempo

1.1 ¿Qué es la complejidad del tiempo?

La complejidad del tiempo es una función que describe cualitativamente el tiempo de ejecución del algoritmo. En el desarrollo de software, la complejidad del tiempo se utiliza para facilitar a los desarrolladores estimar el tiempo de ejecución del programa. Por lo general, el número de unidades operativas del algoritmo se utiliza para representar el tiempo consumido por el programa.Aquí, por defecto, cada unidad de la CPU tarda el mismo tiempo en ejecutarse. Suponiendo que el tamaño del problema del algoritmo es n, entonces el número de unidades operativas está representado por una función . Con el aumento del f(n)tamaño de los datos , la tasa de crecimiento del tiempo de ejecución del algoritmo y la tasa de crecimiento del algoritmo muestran una cierta relación, que se denomina complejidad temporal asintótica del algoritmo, denominada complejidad temporal, denotada como ), donde n se refiere al número de conjuntos de instrucciones.nf(n)O(f(n)

1.2 ¿Qué es la O grande?

big O se utiliza para indicar el límite superior del tiempo de ejecución del algoritmo . También puede entenderse como el tiempo de ejecución en el peor de los casos. La cantidad de datos y la secuencia tienen un gran impacto en el tiempo de ejecución del algoritmo. Aquí se supone que se utilizan ciertos datos de entrada. El tiempo de ejecución de este algoritmo es más largo que el tiempo de cálculo de otros datos.

Todos decimos que la complejidad temporal de la ordenación por inserción es sí O(n^2), pero la complejidad temporal de la ordenación por inserción tiene mucho que ver con los datos de entrada. Si los datos de entrada están completamente ordenados, la complejidad temporal de la ordenación por inserción es, si los datos de O(n)entrada En orden completamente inverso, la complejidad temporal es O(n^2), por lo que en el peor de los casos O(n^2)la complejidad temporal es, decimos que la complejidad temporal de la ordenación por inserción es O(n^2).

La clasificación rápida es O(nlogn)que la complejidad temporal de la clasificación rápida en el peor de los casos es O(n^2), en general O(nlogn), por lo que estrictamente hablando de la definición de O grande, la complejidad temporal de la clasificación rápida debería ser O(n^2) , pero seguimos diciendo que La complejidad temporal de la clasificación rápida es O(nlogn), esta es la regla predeterminada en la industria.

La complejidad temporal de la búsqueda binaria es O(logn)que el tamaño de los datos binarios se reduce a la mitad cada vez hasta que el tamaño de los datos se reduce a 1, y finalmente es equivalente a encontrar cuántas potencias de 2 son iguales a n, lo que equivale a dividir tiempos. logn.

La complejidad temporal de la clasificación por fusión es O(nlogn), fusión de arriba hacia abajo, desde el tamaño de datos n dividido en 1, la complejidad temporal es O (logn), y luego la complejidad temporal de la fusión ascendente continua es, la complejidad temporal general O(n)es O(nlogn).

La complejidad transversal de un árbol es generalmente el número de nodos en el árbol O(n), ny la complejidad temporal de la clasificación de selección es O(n^2). Analizaremos gradualmente la complejidad de cada estructura de datos y algoritmo en los capítulos correspondientes. Para obtener más análisis y derivaciones de la complejidad del tiempo, consulte el teorema principal.

1.3 Complejidad del tiempo común

1.3.1 O(1): complejidad constante
let n = 100;
1.3.2 O (logn): complejidad logarítmica
//二分查找非递归
var search = function (nums, target) {
    
    
  let left = 0,
    right = nums.length - 1;
  while (left <= right) {
    
    
    let mid = Math.floor((left + right) / 2);
    if (nums[mid] === target) {
    
    
      return mid;
    } else if (target < nums[mid]) {
    
    
      right = mid - 1;
    } else {
    
    
      left = mid + 1;
    }
  }
  return -1;
};
1.3.3 O (n): complejidad del tiempo lineal
for (let i = 1; i <= n; i++) {
    
    
  console.log(i);
}
1.3.4 O(n^2): cuadrado (bucle anidado)
for (let i = 1; i <= n; i++) {
    
    
  for (let j = 1; j <= n; j++) {
    
    
    console.log(i);
  }
}
  
for (let i = 1; i <= n; i++) {
    
    
  for (let j = 1; j <= 30; j++) {
    
     //嵌套的第二层如果和n无关则不是O(n^2)
    console.log(i);
  }
}
1.3.5 O(2^n): complejidad exponencial
for (let i = 1; i <= Math.pow(2, n); i++) {
    
    
  console.log(i);
}
1.3.6 O(n!): factorial
for (let i = 1; i <= factorial(n); i++) {
    
    
  console.log(i);
}

2 algoritmos de clasificación comunes

2.1 Clasificación de selección

Pasos del algoritmo:

Primero busque el elemento más pequeño (más grande) en la secuencia no ordenada y 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 restantes sin clasificar y luego colóquelo al final de la secuencia ordenada.

Repita el paso dos hasta que todos los elementos estén ordenados.

La clasificación por selección es un algoritmo de clasificación simple e intuitivo: no importa qué datos se ingresen, la complejidad del tiempo es O (n²). Entonces, al usarlo, cuanto menor sea el tamaño de los datos, mejor. La única ventaja puede ser que no ocupa espacio de memoria adicional.

function selectSort(arr) {
    
    
    for (let i=0;i<arr.length-1;i++) {
    
    
        let min = i;
        for (let j=min+1;j<arr.length;j++) {
    
    
            if (arr[min] > arr[j]) {
    
    
                min = j;
            }
        }
        let temp = arr[i];
        arr[i] = arr[min]
        arr[min] = temp;
    }
    return arr;
}

2.2 Clasificación de burbujas

Compara elementos adyacentes. Si el primero es mayor que el segundo, cámbielos a ambos;

La primera pasada del bucle 0-n determina el valor de n encontrando el valor más grande y burbujeando hacia la parte superior.

El segundo bucle a través de 0-n-1 determina el valor de n-1

El tercer paso recorre 0-n-2 para determinar el valor de n-2.

function bubleSort(arr) {
    
    
    for (let i = 0;i<arr.length-1;i++) {
    
      // 循环轮次
        for (let j=0;j< arr.length-i-1;j++) {
    
     // 每轮比较次数
            if (arr[j] > arr[j+1]) {
    
     // 相邻比较
                let temp = arr[j]
                arr[j] = arr[j+1]
                arr[j+1] = temp
            }
        }
    }
    return arr;
}

2.3 Ordenación por inserción

Los dos primeros valores están ordenados.

El segundo bucle ordena los primeros tres valores, compara el último valor con el nuevo valor y luego lo inserta en la posición especificada.

Insertar descripción de la imagen aquí

Insertar descripción de la imagen aquí

function insertSort(arr) {
    
    
    for (let i = 1;i<arr.length;i++) {
    
      // 循环轮次
        let end = i;
        let curr = arr[i]
        while(end > 0 && curr < arr[end-1]) {
    
     // 直到第一位 或者 当前的数不是最小值
            arr[end] = arr[end - 1] // 移动比当前值小的值到后一位
            end--
        }
        arr[end] = curr // 插入当前值
    }
    return arr;
}

2.4 Operación XOR

El resultado es 1 si y sólo si sólo un bit de la expresión es 1. De lo contrario, el bit del resultado es 0. En pocas palabras, es -----0 para lo mismo y 1 para la diferencia.

Sintaxis: resultado = expresión1 ^ expresión2
按位异或 是对两个表达式执行 按位异或,先将两个数据转化为二进制数,然后进行 按位异或运算,只要位不同结果为 1,否则结果为 0

例如:
let a = 5;
let b = 8;
let c = a ^ b;
console.log(c) // 13

解析:
a 转二进制数为:0101
b 转二进制数为:1000
那么按照 按位异或 运算之后得到:1101(相同为 0,不同为 1),得到 c 的值就是 13
Características

1. Cumplir con el tipo de cambio

a ^ b == b ^ a

2. La operación XOR de dos números idénticos debe dar como resultado 0

a^a === 0

3. 其他数字El resultado obtenido por la operación 0 y XOR debe ser其他数字

0^a === a

2.5 Ejercicios

1. Dada una matriz de enteros no vacía, cada elemento aparece dos veces excepto un elemento que aparece solo una vez. Encuentra el elemento que aparece solo una vez.

let arr = [1, 3, 1, 2, 2, 7, 3, 6, 7]

// es5 解决方案
function fnc(arr){
    
    
    let result = 0;
    for(let i = 0; i < arr.length; i++){
    
    
        result  = result ^ arr[i];
    }
    return result;
}

// es6 解决方案
function fnc(arr){
    
    
    return arr.reduce((a, b) => a ^ b, 0);
}

Supongo que te gusta

Origin blog.csdn.net/sinat_29843547/article/details/128617361
Recomendado
Clasificación