set和map是C++標準庫中的關聯容器,它們中的所有元素都會根據元素的鍵值(key)自動被排序,又由于紅黑樹(RB-tree)是一種平衡二叉搜索樹,自動排序效果非常好,所以標準的STL中的set和map容器都是以紅黑樹(RB-tree)為底層機制,又由于map和set所開放的各種操作接口,RB-tree也提供了,所以它們幾乎所有的操作行為,都只是轉調RB-tree的操作行為。
set介紹:set是存儲已排序的無重復的元素,它有過濾重復功能,它元素的鍵值(key)就是實值(value),實值就是鍵值,所以set的迭代器不能改變其元素值,否則會嚴重破壞其set有序的組織,所以其迭代器被定義為底層RB-tree的const_iterator,杜絕寫入操作。
set源碼:
template< class Key, class Compare = less<Key>, //缺省情況下采用遞增排序 class Alloc = alloc>class set;set幾個重要操作行為接口:
首先要了解接口各元素類型:
其中pair是一個結構體,定義如下:
template <class T1,class T2>struct pair{ typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; pair():first(T1()),second(T2()) {} pair(const T1& a,const T2& b):first(a),second(b) {}}在上插入返回值pair<iterator,bool>則代表插入時第一個返回迭代器即插入位置,第二個插入成功則返回true,插入失敗返回false.
使用練習:
#include <iostream>#include <cstdlib>#include <set>using namespace std;void TestSet(){ set<int> s; //insert使用 for(size_t i=0;i<5;++i) s.insert(i); pair<set<int>::iterator,bool> ret=s.insert(3); if(ret.second==false) { s.insert(ret.first,7); s.insert(ret.first,5); s.insert(ret.first,8); s.insert(ret.first,9); } int arr[]={10,1,9,11,6,13,14}; s.insert(arr,arr+7); set<int>::iterator it; for (it=s.begin(); it!=s.end(); it++) cout << " " << *it; cout << endl; //erase與find使用 s.erase(0); s.erase(14); it=s.find(7); s.erase(it); s.erase(s.find(8)); it=s.begin(); ++it; s.erase(it,s.find(4)); for (it=s.begin(); it!=s.end(); it++) cout << " " << *it; cout << endl;}int main(){ TestSet(); system("pause"); return 0;}運行結果:
map介紹:map的所有元素為pair,同時擁有實值(value)和鍵值(key),pair第一元素為鍵值,第二元素為實值,它不允許兩個元素擁有相同的鍵值,其中可以通過map迭代器修改其元素實值(value),但不能修改鍵值(key),會破壞map有序組織。
map源碼:其中Key為鍵值(key)類型,T為實值(value)類型
template <class Key,class T, class Compare = less<Key>, //缺省采用遞增排序 class Alloc = alloc>class map;map幾個重要操作行為接口:接口各元素類型:
Operator[]實現原理:返回實值(value)的引用
使用練習:
void TestMap(){ map<char,int> m; //inset使用 m.insert(pair<char,int> ('a',10)); m.insert(pair<char,int> ('b',10)); m.insert(pair<char,int> ('d',20)); m.insert(pair<char,int> ('c',30)); pair<map<char,int>::iterator,bool> ret=m.insert(pair<char,int> ('d',40)); if(ret.second==false) { cout<<"Key:"<<ret.first->first<<" value:"<<ret.first->second; cout<<endl; } map<char,int>::iterator it=m.begin(); ++it; m.insert(it,pair<char,int>('f',40)); m.insert(it,pair<char,int> ('e',10)); for ( it=m.begin() ; it != m.end(); it++ ) cout << (*it).first << " :: " << (*it).second << endl; //erase使用 it=m.begin(); ++it; ++it; ++it; m.erase (it); m.erase('e'); it=m.begin(); map<char,int>::iterator it2=m.end(); --it2; m.erase ( it, it2 ); cout<<endl<< "erase使用:"; for ( it=m.begin() ; it != m.end(); it++ ) cout <<(*it).first << " :: " << (*it).second << endl; //operator[]使用 m['a']=10; m['b']=20; m['c']=30; m['d']=40; m['e']=50; m['f']=60; it2=m.find('f'); m.erase(it2); cout<<endl; for ( it=m.begin() ; it != m.end(); it++ ) { cout << (*it).first << " :: " << (*it).second << endl; }}運行結果:
新聞熱點
疑難解答