C++STL基本容器的使用
阿新 • • 發佈:2018-06-04
類型 ace remove stack urn item ont 插入 one
容器主要分為:順序容器和關聯容器
順序容器和關聯容器,順序容器主要有:vector、list、deque等。其中vector表示一段連續的內存地址,基於數組的實現,list表示非連續的內存,基於鏈表實現。deque雙向隊列與vector類似,但是對於首元素提供刪除和插入的雙向支持。關聯容器主要有map和set。map是key-value形式的,set是單值。map和set只能存放唯一的key值,multimap和multiset可以存放多個相同的key值, 還有unorder_multimap等。
順序容器
vector
/*
* 什麽是vector, vector的特點* vector類似一個動態數組,是一段地址連續的空間
* vector和array的區別:vector支持動態空間調整,隨著元素的增加,大小會改變
*/
// 初始化: vector<int> v; vector<int> v2(10); // 可以容納10個int vector<int> v3(10, 2); // 10個2 vector<int> v4(v2); int arr[4] = {1,2,3,4}; vector<int> v5(arr, arr+4);vector常用方法// 其他操作, 是vector容器自帶的函數,不包含全局的算法(find查找,remove_if刪除等) // 添加元素 vec.push_back(3); // 在最後添加元素 insert(); /* iterator insert( iterator loc, const TYPE &val ); void insert( iterator loc, size_type num, const TYPE &val ); void insert( iterator loc, input_iterator start, input_iterator end ); insert() 函數有以下三種用法: 在指定位置loc前插入值為val的元素,返回指向這個元素的叠代器, 在指定位置loc前插入num個值為val的元素 在指定位置loc前插入區間[start, end)的所有元素 .*/ // 刪: // erase iterator erase( iterator loc ); iterator erase( iterator start, iterator end ); // erase函數要麽刪作指定位置loc的元素,要麽刪除區間[start, end)的所有元素. // 返回值是指向刪除的最後一個元素的下一位置的叠代器.例如: vec.clear(); // 清空容器 vec.pop_back(); // 移除尾部元素,無返回值 // 查 vec.back(); // 返回最有一個元素的引用 vec.begin(); // 返回當前容器首元素的叠代器 vec.end(); // 尾後叠代器 vec.rbegin(); // rbegin函數返回指向當前vector末尾的逆叠代器 vec.rend(); // rend()函數返回指向當前vector起始位置的逆叠代器. 類似與begin和end 其他 vec.empty(); // 判斷是否為空 vec.capacity(); // 返回當前vector在重新進行內存分配以前所能容納的元素數量. // reserve()函數為當前vector預留至少共容納size個元素的空間 // void resize( size_type size, TYPE val ); vec.resize(); // resize() 函數改變當前vector的大小為size,且對新創建的元素賦值val vec.size(); // 返回當前所容納的元素個數 // vec.swap(vec2) // vec和vec2交換 // 遍歷: void print(vector<int>& vec) { for (int i = 0; i < vec.size(); i++) cout << vec[i] << " "; for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) { cout << *it << " "; } for (auto item : vec) { cout << item << " "; } cout << endl; }
deque
支持隨機訪問和快速插入和刪除
// 雙向隊列和向量很相似,但是它允許在容器頭部快速插入和刪除(就像在尾部一樣)。
// 就是比vector多了兩個方法:
push_front()
pop_back()
// 具體使用方法參考vector
#include <iostream> #include <algorithm> #include <deque> using namespace std; void printDeq(deque<int> &d1) { cout << "deque叠代器遍歷:"; for (deque<int>::iterator it = d1.begin(); it != d1.end(); it++) { cout << *it << " "; } cout << endl << endl; } void test41() { deque<int> d1; d1.push_back(1); d1.push_back(3); d1.push_back(5); d1.push_front(-11); d1.push_front(-33); d1.push_front(-55); printDeq(d1); cout <<"頭部元素:" << d1.front() << endl; cout <<"尾部元素:" << d1.back() <<endl; d1.pop_front(); // 彈出頭部元素 d1.pop_back(); // 彈出尾部元素 cout << "彈出頭部,和尾部之後: "; printDeq(d1); // 查找-33在數組下標的值 deque<int>::iterator it = find(d1.begin(),d1.end(), -33); if (it != d1.end()) { // 計算下標 cout <<"-33的數組下標是" << distance(d1.begin(), it) << endl; } else { cout <<"未找到"<<endl; } } int main40() { test41(); return 0; }deque例子
list
list,list是stl實現的雙向鏈表,
與向量vector想比,它允許快速的插入和刪除,但是隨機訪問卻是比較慢
結構圖:
優點:隨意插入和刪除,替換元素效率極高
缺點:查找慢(不能隨機訪問:就是只能從頭開始遍歷)
不建議想裏面插入數據,效率太低
/ 其他操作 // 初始化,創建 list<int> lst1; //創建空list list<int> lst2(3); //創建含有三個元素的list list<int> lst3(3,2); //創建含有三個元素為2的list list<int> lst4(lst2); //使用lst2初始化lst4 list<int> lst5(lst2.begin(),lst2.end()); //同lst4 // 增 lst1.assign(lst2.begin(),lst2.end()); //分配值,3個值為0的元素 lst1.push_front(1); // 1加到list的首部 lst1.push_back(10); //末尾添加值 lst1.insert(); //返回值是一個叠代器,指向被插入的元素。 iterator insert( iterator pos, const TYPE &val ); // 插入元素val到位置pos void insert( iterator pos, size_type num, const TYPE &val ); // 插入num個元素val到pos之前 void insert( iterator pos, input_iterator start, input_iterator end ); // 插入start到end之間的元素到pos的位置 // 刪 lst1.pop_back(); // 刪除鏈表的最後一個元素。 lst1.pop_front(); // 刪除連鏈表第一個元素 lst1.remove(1); // 刪除鏈表中所有的1 void lst1.remove_if( UnPred pr)// 以一元謂詞pr為判斷元素的依據,遍歷整個鏈表。如果pr返回true則刪除該元素。 lst1.erase() iterator erase( iterator pos ); iterator erase( iterator start, iterator end ); erase()函數刪除以pos指示位置的元素, 或者刪除start和end之間的元素。 返回值是一個叠代器,指向最後一個被刪除元素的下一個元素。 lst1.clear() // 清除所有元素 // 改 lst1.reverse(); // 將所有的list倒轉 lst1.swap(list2); // 1和2交換 lst1.unique(); // 刪除重復的元素 void unique(); void unique( BinPred pr ); unique()函數刪除鏈表中所有重復的元素。如果指定pr,則使用pr來判定是否刪除。 // 查 lst1.begin(); // 返回list的首元素的叠代器 lst1.end(); // 返回list尾後叠代器 lst1.front(); // 返回一個指向首元素的引用 lst.back() // 返回一個引用,指向list的最後一個元素。 lst1.rbegin(); // 返回一個逆向叠代器,指向鏈表的末尾。 rend和begin和end用法類似 // 其他 lst1.empty(); // 判斷是否為空 true為空 lst1.max_size(); //max_size()函數返回鏈表能夠儲存的元素數目。 lst1.merge() void merge( list &lst ); void merge( list &lst, Comp compfunction ); merge()函數把自己和lst鏈表連接在一起,產生一個整齊排列的組合鏈表。如果指定compfunction,則將指定函數作為比較的依據。 lst1.resize(); void resize( size_type num, TYPE val )// resize()函數把list的大小改變到num。被加入的多余的元素都被賦值為val lst1.size(); // 返回鏈表的元素數量 lst1.sort(); // 排序 void sort(); void sort( Comp compfunction ); sort()函數為鏈表排序,默認是升序。如果指定compfunction的話,就采用指定函數來判定兩個元素的大小。 // 遍歷: // list不能隨機訪問 就是 it++正確,但是不能it+2 it = l.begin(); it++; it++; it++; // 此時it指向第4個元素,元素為3 l.insert(it, 100); // 在3前面插入100 for (auto it = lst1.begin(); it != lst1.end(); it++) cout << *it << " "; for (auto it : lst1) cout << it << " "; // 加上&可以修改值 for (auto& it : lst1) cout << it << " ";list常用操作
stack
不允許遍歷
C++ Stack(堆棧) 是一個容器類的改編,為程序員提供了堆棧的全部功能,——也就是說實現了一個先進後出(FILO)的數據結構。
stack<int> s; s.push(1); // 在棧頂添加元素 s.push(2); s.top(); // 返回棧頂元素 s.pop(); //刪除棧頂元素 s.empty(); // 判斷棧空 s.size(); // 判斷棧中元素數量
// // Created by lk on 18-6-3. // #include <iostream> #include <stack> #include <cstring> #include <algorithm> using namespace std; // 出棧 void printStack(stack<int> &sta) { while(!sta.empty()) { cout << sta.top() << " "; // 獲取棧頂元素 sta.pop(); // 出棧 } } void test51() { stack<int> s; // 入棧 for(int i = 0; i != 10; i++) { s.push(i+1); } printStack(s); } // 棧模型 // 棧的算法 和數據類型的分離 // teacher節點 class Teacher { private: int age; char name[32]; public: Teacher() { age = 0; strcpy(name, ""); } Teacher(char *name, int age) { this->age = age; strcpy(this->name, name); } void print() { cout << "name: " << name << "age: " << age << endl; } friend ostream& operator<<(ostream &out, Teacher &obj) { out << " name: " << obj.name << " age: " << obj.age << endl; return out; } }; // 存放類 類型 void test52() { Teacher t1("t1", 31), t2("t2", 32), t3("t3", 33); stack<Teacher> Stack_Tea; Stack_Tea.push(t1); Stack_Tea.push(t2); Stack_Tea.push(t3); while(!Stack_Tea.empty()) { // Teacher重載了<<所以可以 cout<< cout <<Stack_Tea.top(); Stack_Tea.pop(); } } // 存放 類指針 類型 void test53() { Teacher t1("t1", 31), t2("t2", 32), t3("t3", 33); stack<Teacher*> Stack_Tea; Stack_Tea.push(&t1); Stack_Tea.push(&t2); Stack_Tea.push(&t3); // 出棧 while(!Stack_Tea.empty()) { cout << (* Stack_Tea.top()); // Stack_Tea.top() 就是&t1 Stack_Tea.pop(); } } int main() { // test51(); test52(); // test53(); return 0; }測試
queue
隊列,棧都不能提前分配空間,需要進棧出棧, 不能遍歷,
隊和棧是兩種封裝好的數據結構
back() 返回最後一個元素
empty() 如果隊列空則返回真
front() 返回第一個元素
pop() 刪除第一個元素
push() 在末尾加入一個元素
size() 返回隊列中元素的個數
// // Created by lk on 18-6-3. // #include <iostream> #include <queue> #include <cstring> using namespace std; // 隊列的基本類型 void test61() { queue<int> q; // 隊列,棧都不能提前分配空間,需要進棧出棧 // 入隊 q.push(1); q.push(3); q.push(5); cout << "隊頭元素:" << q.front() << endl; // 返回隊頭元素,不是刪除,棧的是刪除 cout <<"隊的大小:" << q.size() <<endl; cout << "隊尾元素:" << q.back() << endl; // 出隊 cout <<"出隊: "; while(!q.empty()) { cout << q.front() << " "; q.pop(); // 刪除隊頭元素 } } // 隊列的算法 和數據類型分離 // teacher 節點 class Teacher { private: int age; char name[32]; public: Teacher() { age = 0; strcpy(name, ""); } Teacher(char *name, int age) { this->age = age; strcpy(this->name, name); } void print() { cout << "name: " << name << " age: " << age << endl; } friend ostream& operator<<(ostream &out, Teacher &obj) { out << "\tname: " << obj.name << " age: " << obj.age << endl; return out; } }; // 存放類 類型 void test62() { Teacher t1("t1", 31), t2("t2", 32), t3("t3", 33); queue<Teacher> queue_Tea; // 隊列裏面存放的是 Teacher的數據類型 queue_Tea.push(t1); // 入隊 queue_Tea.push(t2); queue_Tea.push(t3); cout << "老師節點的出隊:\n"; while(!queue_Tea.empty()) { cout << queue_Tea.front() << "\n"; queue_Tea.pop(); // 出隊 } } // 存放指針類型 // 類似棧 。。。 int main() { // test61(); test62(); return 0; }測試
關聯容器
https://www.cnblogs.com/xiaokang01/p/9130699.html
C++STL基本容器的使用