1. Ao empurrar um elemento para o vetor, se o número de elementos exceder a capacidade do vetor neste momento, a expansão será acionada
2. O processo de expansão é: abrir novo espaço -> copiar os elementos do antigo espaço -> liberar o antigo espaço
3. O tamanho do novo espaço aberto durante o processo de expansão afeta a eficiência da inserção de elementos no vetor:
- Se o tamanho do novo espaço for o tamanho do antigo espaço + 1, ou seja, a capacidade é expandida durante a inserção, então cada inserção deve ser copiada e a complexidade de tempo é O(n), o que é muito ineficiente
- Se o novo tamanho de espaço for o antigo tamanho de espaço + k, então a complexidade média de tempo de push_back de um elemento ainda será O(n). Calculado da seguinte forma:
- Se o tamanho do novo espaço for m vezes o tamanho do antigo espaço, a complexidade média de tempo de push_back de um elemento é O(1) e a eficiência é bastante aprimorada. Calculado da seguinte forma:
- Geralmente m leva 1,5 ou 2. Quando o valor é 1,5, a memória liberada anteriormente pode ser reutilizada durante cada expansão, enquanto que quando o valor é 2, a memória liberada anteriormente não pode ser reutilizada durante a expansão de capacidade. A explicação é a seguinte:
- Por que m não leva 3 ou 4 ou mais? Porque se o múltiplo exceder 2 vezes (incluindo 2 vezes), a expansão existirá: ① O desperdício de espaço pode ser relativamente alto, por exemplo: após a expansão, 64 espaços são solicitados, mas apenas 33 elementos são armazenados e quase metade do espaço não é usado. ②A memória liberada anteriormente não pode ser usada.
4. Resumo
- A multiplicação do vetor em push_back pode atingir a complexidade do evento O(1) após a amortização, que é melhor do que a complexidade do tempo O(n) de aumentar o tamanho especificado.
- Para evitar o desperdício de memória do aplicativo, os métodos de crescimento de 2 vezes e 1,5 vezes são comumente usados agora, e o método de crescimento de 1,5 vezes pode realizar melhor a reutilização da memória.
5. O tamanho (), capacidade (), resize () e reserva () do vetor
size retorna o número de elementos no vetor
capacidade retorna a capacidade do vetor (capacidade>=tamanho)
resize modifica o tamanho. Se o tamanho n especificado por resize for menor que o tamanho atual, os elementos extras serão excluídos; se n for maior que size e menor que a capacidade atual, serão inseridos valores padrão do elemento n-size ; se n for maior que a capacidade, a capacidade será expandida. capacidade=tamanho=n
reserva modifica o tamanho da capacidade, se o tamanho especificado n for menor ou igual à capacidade atual, nada será feito; se n for maior que a capacidade, a capacidade será expandida para n
6, referência
Pergunta da entrevista: Por que a expansão dinâmica do vetor C++ é 1,5 vezes ou 2 vezes?
Mecanismo de expansão vetorial do STL - programador procurado