STL常用容器解析

STL容器

stl提供了大量成熟的容器供我們存儲數據,在連接各自容器的特點的情況下,選擇性的使用最合適的容器,會使代碼質量與性能大大提升,下面記錄下各自常用容器的特性:

1. std::vector

vector是一種非常常用的數組類型的容器,使用非常方便,但在某些場景下,其數據結構並不能帶來良好的性能優勢。
在這裏插入圖片描述

2. rb_tree(紅黑樹)

這裏不過深的探究紅黑樹的數據結構及其旋轉樹形邏輯,主要是因爲stl中常用的容器如map,set,內部都是封裝的rb_tree來實現其功能的,所以有必要提前瞭解一下紅黑樹的一些規則及簡單使用。
在這裏插入圖片描述

3. set/multiset

set/multiset相當於紅黑樹的一種容器適配器(container adapter),因爲其底層封裝了一個紅黑樹對象,其所有的操作都是由該對象來完成的
在這裏插入圖片描述

#include <set>
#include <stdlib.h> // rand()
#include <time.h>
void TestSet()
{
	std::set<int> mySet = {1, 5,2,8,4};
	for (const auto& i : mySet) {
		std::cout << i << " ";
	}// 1 2 4 5 8
	mySet.insert(5); // b不報錯,但也不會插入

	std::multiset<int> myMultiSet = { 1, 5,2,8,4 };
	for (const auto& i : mySet) {
		std::cout << i << " ";
	}// 1 2 4 5 8
	myMultiSet.insert(5);// 1 2 4 5 5 8
	std::cout << std::endl;
	auto itr = myMultiSet.begin();
	std::cout << *itr;
	// *itr = 2;   // 編譯不通過

	// 測試集合的搜索效率
	// 插入100,0000個隨機元素,可能會存在重複值
	std::multiset<int> bigSet;
	// int 4個字節 取值範圍 -2147483648~2147483647[-2^31~2^31-1]
	// rand()  返回值範圍0~32767
	clock_t start, end;
	start = clock();
	int length = 1000000;
	for (int i = 0; i < length; ++i) {
		bigSet.insert(rand());

	}
	end = clock();
	std::cout << "insert element cost time: " << double(end - start) << "個CPU時鐘單元";//14502

	int findVal = 3456;

	// 用std::find算法查找
	start = clock();
	auto res = std::find(bigSet.begin(), bigSet.end(), findVal);
	end = clock();
	std::cout << "std::find cost time: " << double(end - start) << "個CPU時鐘單元";//27
	if (res != bigSet.end()) {
		std::cout << "Find;";
	}
	else {
		std::cout << "Not Find;";
	}

	//用集合自帶的find接口查找
	start = clock();
	res = bigSet.find(findVal);
	end = clock();
	std::cout << "set.find cost time: " << double(end - start) << "個CPU時鐘單元";//0
	if (res != bigSet.end()) {
		std::cout << "Find;";
	}
	else {
		std::cout << "Not Find;";
	}
	
}

4. map/multimap

map/mmultimap也相當於紅黑樹的一種容器適配器(container adapter),因爲其底層封裝了一個紅黑樹對象,其所有的操作都是由該對象來完成的,與set/multiset的區別在於key與value不同,需要傳入key和data兩個值
在這裏插入圖片描述

#include <map>
void TestMap()
{
	std::map<int, std::string> myMap = { {1, "a"}, {5, "e"}, {3, "c"},{9,"d"} };
	for (const auto& iEle : myMap) {
		std::cout << iEle.first<< " ";
	}// 1 3 5 9
	myMap.insert(std::pair<int, std::string>(5, "g")); // b不報錯,但也不會插入
	myMap[15] = "dfd";
	myMap[1] = "op";

	std::multimap<int, std::string> myMultiMap = { {1, "a"}, {5, "e"}, {3, "c"},{9,"d"} };
	for (const auto& iEle : myMultiMap) {
		std::cout << iEle.first << " ";
	}// 1 2 4 5 8
	myMultiMap.insert(std::pair<int, std::string>(5, "g"));// 1 2 4 5 5 8
	std::cout << std::endl;
	auto itr = myMultiMap.begin();
	itr->second = "gh";
	// myMultiMap[1] = "787"; // 編譯報錯

}

5. std::list

list是一種環狀的雙向鏈表,其插入和刪除元素比較高效
在這裏插入圖片描述

6. std::deque/queue/stack

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章