std::vector 和 std::list 區別?
std::vector 和 std::list 是 C++ 標準庫中兩種不同的容器型別,它們之間有以下幾個主要區別:
- 儲存結構:
- std::vector 是連續記憶體空間上的動態陣列,元素在記憶體中是連續儲存的。
- std::list 是基於雙向連結串列實現的,元素在記憶體中是非連續儲存的。
- 訪問效率:
- std::vector 可以透過下標隨機訪問元素,時間複雜度為 O(1)。
- std::list 需要順序遍歷才能訪問特定元素,時間複雜度為 O(n)。
- 插入和刪除效率:
- std::vector 在中間插入或刪除元素時需要移動其他元素,效率較低,時間複雜度為 O(n)。
- std::list 在任意位置插入或刪除元素都很高效,時間複雜度為 O(1)。
- 記憶體管理:
- std::vector 需要分配連續的記憶體空間,當容量不足時需要重新分配記憶體並複製元素,效率相對較低。
- std::list 在插入和刪除時只需要修改指標,不需要移動元素,效率較高。
- 空間利用率:
- std::vector 由於是連續儲存,可以更好地利用快取,空間利用率較高。
- std::list 由於是連結串列結構,需要額外儲存指標資訊,空間利用率相對較低。
總的來說,std::vector 適合需要快速隨機訪問的場景,std::list 適合需要頻繁插入和刪除的場景。在選擇使用哪種容器時,需要根據具體的應用需求進行權衡。
std::vector 的增刪改查例子
#include <iostream>
#include <vector>
int main() {
// 建立一個空的 std::vector
std::vector<int> v;
// 增
// 在末尾追加元素
v.push_back(1);
v.push_back(2);
v.push_back(3);
// 在指定位置插入元素
v.insert(v.begin() + 1, 4);
// v 此時為 {1, 4, 2, 3}
// 查
// 訪問指定位置的元素
std::cout << "Element at index 2: " << v[2] << std::endl;
// 遍歷所有元素
std::cout << "All elements: ";
for (int i : v) {
std::cout << i << " ";
}
std::cout << std::endl;
// 改
// 修改指定位置的元素
v[2] = 5;
// v 此時為 {1, 4, 5, 3}
// 刪
// 刪除指定位置的元素
v.erase(v.begin() + 1);
// v 此時為 {1, 5, 3}
// 清空 vector
v.clear();
// v 此時為空
return 0;
}
這個例子展示了 std::vector 的基本增刪改查操作:
- 建立一個空的 std::vector。
- 使用
push_back()
在末尾追加元素,使用insert()
在指定位置插入元素。 - 使用下標訪問指定位置的元素,使用
for
迴圈遍歷所有元素。 - 使用下標修改指定位置的元素。
- 使用
erase()
刪除指定位置的元素,使用clear()
清空整個 vector。
std::list 的增刪改查例子
這裡是一個 std::list 的增刪改查操作的例子
#include <iostream>
#include <list>
int main() {
// 建立一個空的 std::list
std::list<int> lst;
// 增
// 在末尾追加元素
lst.push_back(1);
lst.push_back(2);
lst.push_back(3);
// 在頭部插入元素
lst.push_front(4);
// lst 此時為 {4, 1, 2, 3}
// 查
// 訪問頭部元素
std::cout << "Head element: " << lst.front() << std::endl;
// 訪問尾部元素
std::cout << "Tail element: " << lst.back() << std::endl;
// 遍歷所有元素
std::cout << "All elements: ";
for (int i : lst) {
std::cout << i << " ";
}
std::cout << std::endl;
// 改
// 修改指定位置的元素
auto it = lst.begin();
std::advance(it, 2);
*it = 5;
// lst 此時為 {4, 1, 5, 3}
// 刪
// 刪除頭部元素
lst.pop_front();
// 刪除尾部元素
lst.pop_back();
// 刪除指定元素
lst.remove(5);
// lst 此時為 {1, 3}
// 清空 list
lst.clear();
// lst 此時為空
return 0;
}
這個例子展示了 std::list 的基本增刪改查操作:
- 建立一個空的 std::list。
- 使用
push_back()
在末尾追加元素,使用push_front()
在頭部插入元素。 - 使用
front()
訪問頭部元素,使用back()
訪問尾部元素,使用for
迴圈遍歷所有元素。 - 使用迭代器
advance()
移動到指定位置,然後修改元素。 - 使用
pop_front()
刪除頭部元素,使用pop_back()
刪除尾部元素,使用remove()
刪除指定元素,使用clear()
清空整個 list。
std::list 查詢某個特定元素如何查詢
在 std::list 中查詢特定元素有幾種方法:
1 使用 find()
演算法:
#include <iostream>
#include <list>
#include <algorithm>
int main() {
std::list<int> lst = {1, 2, 3, 4, 5};
// 查詢元素 3
auto it = std::find(lst.begin(), lst.end(), 3);
if (it != lst.end()) {
std::cout << "Found element: " << *it << std::endl;
} else {
std::cout << "Element not found" << std::endl;
}
return 0;
}
2 使用 std::list
的成員函式 find()
:
#include <iostream>
#include <list>
int main() {
std::list<int> lst = {1, 2, 3, 4, 5};
// 查詢元素 3
auto it = lst.find(3);
if (it != lst.end()) {
std::cout << "Found element: " << *it << std::endl;
} else {
std::cout << "Element not found" << std::endl;
}
return 0;
}
3 使用 std::find_if()
演算法,傳入一個自定義的謂詞函式:
#include <iostream>
#include <list>
#include <algorithm>
bool isEven(int x) {
return x % 2 == 0;
}
int main() {
std::list<int> lst = {1, 2, 3, 4, 5};
// 查詢第一個偶數元素
auto it = std::find_if(lst.begin(), lst.end(), isEven);
if (it != lst.end()) {
std::cout << "Found element: " << *it << std::endl;
} else {
std::cout << "Element not found" << std::endl;
}
return 0;
}
以上三種方法都可以用來在 std::list 中查詢特定元素。其中,使用 std::find()
演算法和 std::list
的成員函式 find()
可以查詢特定值的元素,而使用 std::find_if()
演算法可以查詢滿足自定義條件的元素。