1. 程式人生 > >STL的使用和背後數據結構

STL的使用和背後數據結構

空間配置器 rar format ear num 技術 位數 png size

STL(Standard Template Library即,模板庫)包括六個部分:容器(containers)、叠代器(iterators)、空間配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函數(functors)

1、vector:連續存儲

(1)頭文件,#include<vector>

(2)創建vector對象,vector<int> vec;

(3)尾部插入元素,vec.push_back(a);

(4)使用下標訪問元素,cout<<vec[0]<<endl;

(5)使用叠代訪問元素

 1 vector<int
>::iterator it; 2 for(it=vec.begin();it!=vec.end();it++) 3 cout<<(*it)<<endl;

(6)插入元素,vec.insert(vec.begin()+i,a);在第i+1個元素前面插入a

(7)刪除元素,vec.erase(vec.begin()+2);刪除第3個元素

        vec.erase(vec.begin()+i,vec.end()+j);刪除區間[i,j-1];區間從0開始

(8)向量大小,vec.size();

(9)清空,vec.clear();

vector的元素不僅僅只限於int型,int、double、string、全局結構體等都可以。

技術分享
 1 #include<iostream>
 2 #include<vector>
 3 using namespace std;
 4 
 5 struct Student
 6 {
 7     int num;
 8     double score;
 9     double operator< (const Student &stu) const
10     {
11         if(stu.score>score)
12             return stu.score;
13         else
14             return
score; 15 } 16 }; 17 18 int main() 19 { 20 vector<Student> stu; 21 //student 1 22 Student stu_temp; 23 stu_temp.num = 1; 24 stu_temp.score =9.9; 25 stu.push_back(stu_temp); 26 //student 2 27 Student stu_temp1; 28 stu_temp1.num = 2; 29 stu_temp1.score =8.8; 30 stu.push_back(stu_temp1); 31 //student 3 32 Student stu_temp2; 33 stu_temp2.num = 3; 34 stu_temp2.score =7.7; 35 stu.push_back(stu_temp2); 36 //print all the students 37 cout<<"the number of student:"<<stu.size()<<endl; 38 vector<Student>::iterator it; 39 for(it=stu.begin();it!=stu.end();it++) 40 cout<<"number:"<<(*it).num<<" score:"<<(*it).score<<endl; 41 //delete one student 42 stu.erase(stu.begin()+1); 43 cout<<endl; 44 cout<<"the number of student:"<<stu.size()<<endl; 45 for(it=stu.begin();it!=stu.end();it++) 46 cout<<"number:"<<(*it).num<<" score:"<<(*it).score<<endl; 47 //print the better score 48 double _result = stu_temp<stu_temp1; 49 cout<<endl; 50 cout<<"the better score:"<<_result<<endl; 51 52 return 0; 53 }
vector_sample

2、string

平時最常用的一個,這裏就不做過多說明了

3、map:關聯容器,提供一對一的數據映射(關鍵字,值);數據結構為紅黑樹(RB-Tree)

  關鍵字只能在map中出現一次;另外,map內部自建一顆紅黑樹(一種非嚴格意義上的平衡二叉樹),這顆樹具有對數據自動排序的功能,所以在map內部所有的數據都是有序的;

(1)頭文件,#include<map>;

(2)創建map對象,map<int,string> mapStudent;

(3)插入數據,

第一種:用insert函數插入pair數據

 1 mapStudent.insert(pair<int,string>(1,"Christal"));
 2 mapStudent.insert(pair<int,string>(2,"Carl"));

第二種:用insert函數插入value_type數據

 1 mapStudent.insert(map<int,string>::value_type (1,"Christal"));
 2 mapStudent.insert(map<int,string>::value_type (2,"Carl"));

第三種:用數組方式插入數據

 1 mapStudent[1] = "Christal";
 2 mapStudent[2] = "Carl";

輸出均為:

技術分享

  如果用前兩種方法插入數據,因為關鍵字是唯一的,所以當關鍵字已經存在的時候,再插入相同關鍵字的map是不成功的;而第三種用數組插入的方法是仍然可以的,會將原來的關鍵字所對應的值進行更改,相當於被覆蓋掉了。

  所以要想知道前兩種方法的插入是否成功,應該用一個返回值來檢驗。

技術分享
 1 #include<iostream>
 2 #include<string>
 3 #include<map>
 4 using namespace std;
 5 int main()
 6 {
 7     map<int,string> mapStudent;
 8     pair<map<int,string>::iterator,bool> insert_pairl;
 9 
10     //insert 1 and check
11     insert_pairl = mapStudent.insert(pair<int,string>(1,"Christal"));
12     if(insert_pairl.second == true)
13         cout<<"Insert Successfully"<<endl;
14     else
15         cout<<"Insert Failure"<<endl;
16 
17     //insert 2 and check
18     insert_pairl = mapStudent.insert(pair<int,string>(2,"Carl"));
19     if(insert_pairl.second == true)
20         cout<<"Insert Successfully"<<endl;
21     else
22         cout<<"Insert Failure"<<endl;
23 
24     //insert 3 and check
25     insert_pairl = mapStudent.insert(pair<int,string>(1,"Jerry"));
26     if(insert_pairl.second == true)
27         cout<<"Insert Successfully"<<endl<<endl;
28     else
29         cout<<"Insert Failure"<<endl<<endl;
30 
31     //print
32     map<int,string>::iterator it;
33     for(it=mapStudent.begin();it!=mapStudent.end();it++)
34         cout<<(*it).first<<" "<<(*it).second<<endl;
35 
36     return 0;
37 }
map_insert_check

  正如上面所說,當要插入的關鍵字已經存在,是插入失敗的,所以輸出結果為:

技術分享

  而采用數組插入方式會直接覆蓋

1 mapStudent[1] = "Christal";
2 mapStudent[2] = "Carl";
3 mapStudent[1] = "Jerry";

  輸出結果為:

技術分享

(4)數據的遍歷,當然分為用叠代器遍歷的方式和用數組遍歷的方式,其中以叠代器遍歷中又分為正向遍歷和反向遍歷,正向遍歷就是我們所熟知的叠代器遍歷方式,反向遍歷如下:

 1 map<int,string>::iterator it; //print
 2 for(it=mapStudent.begin();it!=mapStudent.end();it++)
 3     cout<<(*it).first<<" "<<(*it).second<<endl;
4 5 map<int,string>::reverse_iterator rit; //reverse print 6 for(rit=mapStudent.rbegin();rit!=mapStudent.rend();rit++) 7 cout<<(*rit).first<<" "<<(*rit).second<<endl;

輸出結果為:

技術分享

(5)查找數據,一是用count()函數查找,存在返回1,否者返回0;二是用find()函數來定位數據出現的位置;

  find()函數返回一個叠代器,如果找到數據,則返回數據所在位置的叠代器;如果不存在,則返回值與end()函數的返回值相同;

 1 map<int,string>::iterator _iter;
 2 _iter = mapStudent.find(1);
 3 if(_iter != mapStudent.end())
 4     cout<<"Find Successfully"<<endl;
 5 else
 6     cout<<"Find Failure"<<endl;

(6)刪除數據,clear()和erase()

  清空map中的所有數據用clear()函數,判定map中是否有數據用empty()函數,為空返回true。

  選擇性的刪除用erase()函數,可以實現三種方式的刪除,

用叠代器刪除:

1 map<int,string>::iterator _iter;
2 _iter = mapStudent.find(1);
3  mapStudent.erase(_iter);

用關鍵字刪除:

1 int n = mapStudent.erase(1);
2if(n == 1)
3     cout<<"Erase Successfully"<<endl;
4else
5     cout<<"Erase Failure"<<endl;

用叠代器成片刪除,刪除區間是一個前閉後開[ )的集合:

 1 mapStudent.erase(mapStudent.begin(),mapStudent.end());

4、set:用來存儲同一數據類型的數據,內部每個元素都是唯一的,且自動排序;數據結構為紅黑樹(RB-Tree)

(1)構造函數,set<int> c;

(2)查找函數,find()函數和count()函數;

(3)數據訪問函數,begin()、end()、rbegin()、rend();

(4)插入數據,insert(element)、insert(position,element)、insert(begin,end);

(5)刪除數據,erase(position)、erase(element)、erase(begin,end);

5、hash_map和hash_set:底層數據結構是哈希表

  hash_map與map用法類似,只是內部數據結構不同,hash_map提供內部數據隨機、更快的訪問;hash_set同理。

6、總結:

(1)vector封裝數組,list封裝鏈表,map和set封裝了二叉樹;

(2)對於這些STL,應當掌握基本的插入、刪除、排序、查找等操作;

(3)對於結構體類型的vector、map、set、hash_map、hash_set等,需要對運算符 ‘ < ’ 進行重載。

  例如在map中引入結構體,對 ‘ < ’ 運算符進行重載:

 1 #include<iostream>
 2 #include<string>
 3 #include<map>
 4 using namespace std;
 5 
 6 struct Student
 7 {
 8     int num;
 9     string name;
10     Student(int nu,string na) //constructor
11     {
12         name = na;
13         num = nu;
14     }
15 public:
16     bool operator< (const Student& stu) const //operator the <
17     {
18         return stu.num<num;
19     }
20 };
21 
22 int main()
23 {
24     map<Student,double> mapStudent;
25     //student information
26     Student stu1(1,"Christal");
27     Student stu2(2,"Carl");
28     Student stu3(3,"Jerry");
29     //insert
30     mapStudent.insert(pair<Student,double>(stu1,9.9));
31     mapStudent.insert(pair<Student,double>(stu2,8.8));
32     mapStudent.insert(pair<Student,double>(stu3,7.7));
33     //print
34     map<Student,double>::iterator it;
35     for(it=mapStudent.begin();it!=mapStudent.end();it++)
36         cout<<(*it).first.num<<" "<<(*it).first.name<<" "<<(*it).second<<endl;
37 
38     return 0;
39 }

STL的使用和背後數據結構