這篇文章是寫算法的時候關於C++數據結構通過自己+各篇其餘文章得來,以做記錄
vector
動態數組
vector<int> v(10) //初始化了10個默認值爲0的元素
vector<int> v(10,1)// 初始化了10個值爲1的元素
vector<vector<int> > v(10, vector<int>(8, 1))// 10行8列全部爲1
int m = v.size()//獲取行
int n = v[0].size()// 獲取列
vector<char> v11({ 'O','X','X','O','X' });
vector<vector<char>> vx({ {'O','X','O','O','O','X'} ,
{ 'O','O','X','X','X','O'},
{'X','X','X','X','X','O'},
{'O','O','O','O','X','X'},
{'X','X','O','O','X','O'} ,
{'O','O','X','X','X','X'} });
pair
pair是將2個數據組合成一組數據,當需要這樣的需求時就可以使用pair,如
- stl中的map就是將key和value放在一起來保存。另一個應用是,當一個函數需要返回2個數據的時候,可以選擇pair。
- pair的實現是一個結構體,主要的兩個成員變量是first second 因爲是使用struct不是class,所以可以直接使用pair的成員變量。
其標準庫類型–pair類型定義在#include 頭文件中
初始化和操作
pair<T1, T2> p1; //創建一個空的pair對象(使用默認構造),它的兩個元素分別是T1和T2類型,採用值初始化。
p1.first; // 返回對象p1中名爲first的公有數據成員
p1.second; // 返回對象p1中名爲second的公有數據成員
生成
pair<T1, T2> p1(v1, v2); //創建一個pair對象,它的兩個元素分別是T1和T2類型,其中first成員初始化爲v1,second成員初始化爲v2。
make_pair(v1, v2); // 以v1和v2的值創建一個新的pair對象,其元素類型分別是v1和v2的類型。
比較
p1 < p2; // 兩個pair對象間的小於運算,其定義遵循字典次序:如 p1.first < p2.first 或者 !(p2.first < p1.first) && (p1.second < p2.second) 則返回true。
p1 == p2; // 如果兩個對象的first和second依次相等,則這兩個對象相等;該運算使用元素的==操作符。
都是一樣的make_pair()顯得更加方便無需寫出型別, 就可以生成一個pair對象
map
map是STL的一個關聯容器,它提供一對一的hash。
第一個可以稱爲關鍵字(key),每個關鍵字只能在map中出現一次;
第二個可能稱爲該關鍵字的值(value);
map<string,vector<string>> m //string 到 vector< string >映射
//插入 即當map中有這個關鍵字時,insert操作是不能在插入數據的,但是用數組方式就不同了,它可以覆蓋以前該關鍵字對 應的值
m.insert(pair<string, vector<string>>("777",vector<string>())
m["123"]=vector<string>()
m["123"].push_back("hhh")
m["123"].push_back("xxx")
m["123"]="aaa"
//刪除
m.erase("123")
// 使用find()方法對集合進行檢索,如果找到查找的的鍵值,則返回該鍵值的迭代器位置;否則,返回集合最後一個元素後面的一個位置,即end()
m.find("666")
m.find("666")!=m.end()
map 與 unordered_map
map: 內部實現了一個紅黑樹(紅黑樹是非嚴格平衡二叉搜索樹,而AVL是嚴格平衡二叉搜索樹),紅黑樹具有自動排序的功能,因此map內部的所有元素都是有序的,紅黑樹的每一個節點都代表着map的一個元素。因此,對於map進行的查找,刪除,添加等一系列的操作都相當於是對紅黑樹進行的操作。map中的元素是按照二叉搜索樹(又名二叉查找樹、二叉排序樹,特點就是左子樹上所有節點的鍵值都小於根節點的鍵值,右子樹所有節點的鍵值都大於根節點的鍵值)存儲的,使用中序遍歷可將鍵值按照從小到大遍歷出來。
unordered_map: 內部實現了一個哈希表(也叫散列表,通過把關鍵碼值映射到Hash表中一個位置來訪問記錄,查找的時間複雜度可達到O(1),其在海量數據處理中有着廣泛應用)。因此,其元素的排列順序是無序的。哈希表詳細介紹
#include <iostream>
#include <unordered_map>
#include <map>
#include <string>
using namespace std;
int main()
{
map<int, string> map = { { 1, "一" },{ 3, "三" },{2,"二"},{4,"四"} };
auto iter = map.begin();
while (iter != map.end())
{
cout << iter->first << "," << iter->second << endl;
++iter;
}
cout << endl;
unordered_map<int, string> unmap = { { 1, "一" },{ 3, "三" },{2,"二"},{4,"四"} };
auto uniter = unmap.begin();
while (uniter != unmap.end())
{
cout << uniter->first << "," << uniter->second << endl;
++uniter;
}
}
set 集合
實現了紅黑樹(Red-Black Tree)的平衡二叉檢索樹的數據結構,在插入元素時,它會自動調整二叉樹的排列,把該元素放到適當的位置,以確保每個子樹根節點的鍵值大於左子樹所有節點的鍵值,而小於右子樹所有節點的鍵值;另外,還得確保根節點的左子樹的高度與有字數的高度相等,
這樣,二叉樹的高度最小,從而檢索速度最快。要注意的是,它不會重複插入相同鍵值的元素,而採取忽略處理。
set<string> visit
visit.insert("666")
visit.erase("666")
// 使用find()方法對集合進行檢索,如果找到查找的的鍵值,則返回該鍵值的迭代器位置;否則,返回集合最後一個元素後面的一個位置,即end()。
visit.find("666")
visit.find("666")!=visit.end()
set與unordered_set區別和map與unordered_map區別類似:
set基於紅黑樹實現,紅黑樹具有自動排序的功能,因此map內部所有的數據,在任何時候,都是有序的。
unordered_set基於哈希表,數據插入和查找的時間複雜度很低,幾乎是常數時間,而代價是消耗比較多的內存,無自動排序功能。底層實現上,使用一個下標範圍比較大的數組來存儲元素,形成很多的桶,利用hash函數對key進行映射到不同區域進行保存
priority_queue 優先隊列
既然是隊列那麼先要包含頭文件#include , 他和queue不同的就在於我們可以自定義其中數據的優先級, 讓優先級高的排在隊列前面,優先出隊
//升序隊列
priority_queue <int,vector<int>,greater<int> > q;
//降序隊列
priority_queue <int,vector<int>,less<int> >q;
其他操作與其他一致
string
string x="Hello_World";
/*默認截取從0到npos.重載原型爲string substr(_off=0,_count=npos);npos一般表示爲string類中不存在的位置,_off表示字符串的開始位置,_count截取的字符的數目*/
cout<<x.substr()<<endl;
cout<<x.substr(5)<<endl;//截取x[5]到結尾,即npos.重載原型爲string substr(_off,_count=npos)
cout<<x.substr(0,5)<<endl;//以x[0]爲始,向後截取5位(包含x[0]),重載原型string substr(_off,_count)
find 沒有規定兩邊,只有開始的pos查找後續所有