[Noções básicas de algoritmo (1)] Compreenda a complexidade do tempo e os algoritmos de classificação comumente usados

1 Compreenda a complexidade do tempo

1.1 O que é complexidade de tempo?

A complexidade do tempo é uma função que descreve qualitativamente o tempo de execução do algoritmo. No desenvolvimento de software, a complexidade do tempo é usada para facilitar aos desenvolvedores estimar o tempo de execução do programa. O número de unidades operacionais do algoritmo é geralmente usado para representar o tempo consumido pelo programa. Aqui, por padrão, cada unidade da CPU leva o mesmo tempo para ser executada. Supondo que o tamanho do problema do algoritmo seja n, então o número de unidades de operação é f(n)representado por uma função. À medida que o tamanho dos dados naumenta, a taxa de crescimento do tempo de execução do algoritmo e f(n)a taxa de crescimento mostram uma certa relação. Isso é chamado de assintótico complexidade de tempo do algoritmo. , referida como complexidade de tempo, denotada como O(f(n)), onde n se refere ao número de conjuntos de instruções.

1.2 O que é grande O

Big O é usado para representar o limite superior do tempo de execução do algoritmo . Também pode ser entendido como o tempo de execução no pior caso. A quantidade e a ordem dos dados têm um grande impacto no tempo de execução do algoritmo. Supõe-se aqui, um determinado dado de entrada é usado. O tempo de execução deste algoritmo é maior que o tempo de cálculo de outros dados.

Todos dizemos que a complexidade de tempo da classificação por inserção é O(n^2), mas a complexidade de tempo da classificação por inserção tem uma ótima relação com os dados de entrada.Se os dados de entrada estiverem completamente ordenados, a complexidade de tempo da classificação por inserção é, se os dados de entrada O(n)forem In ordem completamente inversa, a complexidade do tempo é O(n^2), então a O(n^2)complexidade do tempo do pior caso é, dizemos que a complexidade do tempo da classificação por inserção é O(n^2).

A classificação rápida é O(nlogn)que a complexidade de tempo da classificação rápida no pior caso é O(n^2), em geral O(nlogn), estritamente falando a partir da definição de grande O, a complexidade de tempo da classificação rápida deveria ser O(n^2) , mas ainda estamos dizendo que o a complexidade de tempo da classificação rápida é O(nlogn), esta é a regra padrão na indústria.

A complexidade de tempo da pesquisa binária é O(logn)que o tamanho dos dados é reduzido pela metade a cada vez até que o tamanho dos dados seja reduzido para 1. Finalmente, é equivalente a encontrar a potência de 2 igual a n, o que equivale a dividi-la por vezes logn.

A complexidade de tempo da classificação por mesclagem é O(nlogn), para fusão de cima para baixo, a complexidade de tempo é O (logn) quando a escala de dados é dividida de n para 1, e então a complexidade de tempo da fusão ascendente contínua é, e a complexidade de tempo geral O(n)é O(nlogn).

A complexidade de travessia de uma árvore é geralmente O(n), nque é o número de nós na árvore, e a complexidade temporal da classificação de seleção, que é O(n^2). Analisaremos gradualmente a complexidade de cada estrutura de dados e algoritmo nos capítulos correspondentes. Mais análises e derivações de complexidade de tempo podem ser encontradas no teorema principal.

1.3 Complexidade de tempo comum

1.3.1 O(1): complexidade constante
let n = 100;
1.3.2 O(logn): complexidade 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): complexidade de tempo linear
for (let i = 1; i <= n; i++) {
    
    
  console.log(i);
}
1.3.4 O(n^2): quadrado (loop aninhado)
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): complexidade exponencial
for (let i = 1; i <= Math.pow(2, n); i++) {
    
    
  console.log(i);
}
1.3.6 O(n!): fatorial
for (let i = 1; i <= factorial(n); i++) {
    
    
  console.log(i);
}

2 algoritmos de classificação comuns

2.1 Ordenação por seleção

Etapas do algoritmo:

Primeiro encontre o menor (maior) elemento na sequência não classificada e armazene-o no início da sequência classificada.

Em seguida, continue a encontrar o menor (maior) elemento entre os elementos não classificados restantes e coloque-o no final da sequência classificada.

Repita a segunda etapa até que todos os elementos estejam classificados.

A classificação por seleção é um algoritmo de classificação simples e intuitivo; não importa quais dados entrem, ele tem uma complexidade de tempo de O (n²). Portanto, quando for usado, quanto menor o tamanho dos dados, melhor. A única vantagem pode ser que não ocupa espaço adicional na memória.

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 Classificação por bolhas

Compare elementos adjacentes. Se o primeiro for maior que o segundo, troque os dois;

A primeira passagem faz um loop 0-n para determinar o valor de n é encontrar o maior valor e borbulhar no topo

O segundo loop através de 0-n-1 determina o valor de n-1

A terceira passagem faz um loop 0-n-2 para determinar o 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 Ordenação por inserção

Os dois primeiros valores são classificados

Classifique os três primeiros valores no segundo ciclo, compare o último valor com o novo valor e insira-o na posição especificada

insira a descrição da imagem aqui

insira a descrição da imagem aqui

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 Operação XOR

Um bit do resultado é 1 se e somente se esse bit for 1 em apenas uma das expressões. Caso contrário, o bit do resultado é 0, simplesmente ----- o mesmo é 0, a diferença é 1

Sintaxe: resultado = expressão1 ^ expressão2
按位异或 是对两个表达式执行 按位异或,先将两个数据转化为二进制数,然后进行 按位异或运算,只要位不同结果为 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. Conheça a taxa de câmbio

a ^ b == b ^ a

2. A operação XOR de dois números idênticos deve resultar em 0

a^a === 0

3. 其他数字O resultado obtido pela operação 0 e XOR deve ser其他数字

0^a === a

2.5 Exercícios

1. Dada uma matriz inteira não vazia, cada elemento aparece duas vezes, exceto um elemento que aparece apenas uma vez. Encontre o elemento que aparece apenas uma 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);
}

Acho que você gosta

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