目錄
- 1. 特性
- 2. 常用成員函式
- 2.1 建構函式
- 2.2 元素訪問
- 2.3 修改容器
- 2.4 容量相關
- 2.5 迭代器
- 3. 記憶體管理與效率
- 4. 示例:
- 5. 效能分析:
std::vector
是 C++ 標準庫中的一個動態陣列容器,位於 #include <vector>
標頭檔案中。它是一個模板類,可以儲存任何型別的物件,並根據需要動態調整其大小。std::vector
提供了高效的隨機訪問、尾部插入/刪除操作(O(1)),但在中間插入或刪除元素的效能較差(O(n))。
1. 特性
- 動態大小:
std::vector
能自動調整大小,隨著元素的增加,容量會自動擴充套件。 - 連續記憶體儲存:由於
std::vector
的儲存空間是連續的,它支援像陣列一樣的隨機訪問,時間複雜度為 O(1)。 - 自動管理記憶體:
std::vector
自動管理記憶體的分配和釋放,不需要手動呼叫new
和delete
。 - 模板類:可以儲存任意型別的物件,必須在建立
std::vector
時指定儲存的物件型別,例如std::vector<int>
儲存整數,std::vector<std::string>
儲存字串。 - 支援範圍檢查:透過
at()
方法訪問元素時會進行範圍檢查,如果索引越界會丟擲std::out_of_range
異常,而使用operator[]
則不會進行檢查。
2. 常用成員函式
2.1 建構函式
std::vector<T> v;
:建立一個空的向量。std::vector<T> v(n);
:建立一個包含n
個預設值為T()
的元素的向量。std::vector<T> v(n, value);
:建立一個包含n
個值為value
的元素的向量。std::vector<T> v{elements...};
:透過初始化列表來初始化std::vector
。
2.2 元素訪問
v[i]
:返回向量中第i
個元素(不進行邊界檢查)。v.at(i)
:返回向量中第i
個元素(進行邊界檢查)。v.front()
:返回第一個元素。v.back()
:返回最後一個元素。v.data()
:返回指向儲存陣列的指標。
2.3 修改容器
v.push_back(value)
:在向量的末尾新增元素value
。v.pop_back()
:刪除向量中的最後一個元素。v.insert(iterator, value)
:在指定位置插入元素。v.erase(iterator)
:刪除指定位置的元素。v.clear()
:刪除所有元素,使向量為空。v.resize(n)
:調整向量大小為n
,若n
大於當前大小,增加的元素將初始化為預設值。v.reserve(n)
:預留空間至少能容納n
個元素,避免多次分配記憶體。
2.4 容量相關
v.size()
:返回向量中當前元素的數量。v.capacity()
:返回向量當前容量,即不重新分配記憶體的情況下,最多能容納多少元素。v.empty()
:判斷向量是否為空。
2.5 迭代器
v.begin()
:返回指向第一個元素的迭代器。v.end()
:返回指向最後一個元素之後的迭代器。v.rbegin()
:返回指向最後一個元素的反向迭代器。v.rend()
:返回指向第一個元素之前的反向迭代器。
3. 記憶體管理與效率
-
std::vector
的記憶體分配具有一定的增長策略,當容量不足時,會重新分配一個更大的記憶體塊(通常是當前容量的 1.5 倍或 2 倍),並將現有元素複製到新的記憶體塊中。這種策略可以減少多次分配和複製的開銷,但也可能導致暫時的記憶體浪費。 -
使用
reserve()
可以預先分配足夠的空間,從而避免多次擴容帶來的開銷,特別是在可以預測元素數量時。 -
shrink_to_fit()
:這個方法請求減少容量以匹配大小,不過實現可以選擇忽略此請求。它可能會將未使用的空間釋放給作業系統。
4. 示例:
#include <iostream>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// 新增元素
v.push_back(6);
// 訪問元素
std::cout << "Element at index 2: " << v[2] << std::endl;
std::cout << "First element: " << v.front() << std::endl;
std::cout << "Last element: " << v.back() << std::endl;
// 修改元素
v[1] = 10;
// 輸出向量的所有元素
for (int x : v) {
std::cout << x << " ";
}
std::cout << std::endl;
// 刪除最後一個元素
v.pop_back();
// 輸出當前大小和容量
std::cout << "Size: " << v.size() << std::endl;
std::cout << "Capacity: " << v.capacity() << std::endl;
return 0;
}
5. 效能分析:
- 時間複雜度:
- 訪問元素的時間複雜度為 O(1)。
- 在尾部插入或刪除元素的時間複雜度為攤銷 O(1),因為擴充套件操作在多次插入後才會觸發。
- 插入或刪除元素(非尾部)的時間複雜度為 O(n),因為插入或刪除操作需要移動後續元素。
- 記憶體重分配開銷:擴充套件向量容量時會進行記憶體重分配,這時所有的元素會被複制到新的記憶體地址,因此在頻繁插入大量元素時,提前使用
reserve()
可以提高效率。
std::vector
是 C++ 中最常用的容器之一,因其靈活的動態陣列功能、優秀的效能和易用性而廣受歡迎。儘管它的動態擴充套件會有一定的開銷,但透過適當的預分配(使用 reserve()
)和合理的使用方式,std::vector
可以滿足大多數應用場景中的效能需求。