關於C++STL中set集合容器的學習,看別人的代碼一百遍,不如自己動手寫一遍。
構造set集合容器的目的是為了去重+排序+快速搜索。由於set集合容器實現了紅黑樹多的平衡二叉檢索樹的數據結構,在插入或者刪除是,均能自動調整二叉樹,使得二叉樹始終保持新的平衡。除set外,multiset,map,multimap的內部結構也是平衡二叉樹。
1 /*關於C++STL中set集合容器的學習,看別人的代碼一百遍,不如自己動手寫一遍。 2 set集合容器的主要目的是為了加快檢索,當有某種數據類型需要去重加排序的時候,使用起來去重非常方便, 3 而且查找效率非常高。 4 */ 5 #include <set>//頭文件,與multiset相同 6 #include <iostream> 7 using namespace std; 8 9 //自定義比較函數myComp,重載"()"操作符 10 struct myComp{ 11 bool operator () (const int &a,const int &b){ 12 return a>b;//由大到小 13 } 14 }; 15 16 //直接將比較函數寫在結構體內 17 struct STUDENT{ 18 string name; 19 double score; 20 21 //重載"<"操作符,自定義排列規則 22 bool operator < (const STUDENT &a) const{ 23 //按score由大到小排列。如果由小到大排列,使用">"號即可 24 return a.score < score; 25 } 26 }; 27 28 void print(set<int> s); 29 void rprint(set<int> s); 30 31 int main() 32 { 33 /*創建set集合對象,格式為set<元素類型> 集合對象標識符*/ 34 set<int> s;//定義了一個元素類型為int的集合對象s,當前沒有任何元素 35 36 /*元素的插入和遍歷(對平衡二叉檢索樹的中序遍歷)*/ 37 //插入過程也是排序過程,排序采用默認的比較規則,使得set集合的數據結構始終保持平衡二叉檢索樹 38 //也可以自定義比較規則函數 39 s.insert(8);//第一次插入8,可以插入 40 s.insert(1); 41 s.insert(6); 42 s.insert(12); 43 s.insert(8);//第二次插入8,重復元素,不可以插入,從而達到去重的效果 44 45 //中序正向遍歷集合中的所有元素 46 set<int>::iterator it;//定義前向迭代器 47 for(it=s.begin(); it != s.end(); it++){ 48 cout<<*it<<' '; 49 } 50 cout<<endl; 51 /*運行結果 52 1 6 8 12 53 */ 54 //中序反向遍歷集合中的所有元素 55 set<int>::reverse_iterator rit; 56 for(rit=s.rbegin(); rit != s.rend();rit++){ 57 cout<<*rit<<' '; 58 } 59 cout<<endl; 60 /*運行結果 61 12 8 6 1 62 */ 63 64 /*要想檢索集合中是否存在等於某個鍵值的元素,則使用find()方法,如果找到則返回該鍵值的迭代器位置, 65 否則,返回集合最后一個元素后面的一個位置,即end()*/ 66 set<int>::iterator it1;//定義迭代器接收find()方法的返回值 67 it1=s.find(12); 68 if(it1 != s.end()) 69 cout<<"找到鍵值為 "<<*it1<<"的元素\n"; 70 it1=s.find(2); 71 if(it1 == s.end()) 72 cout<<"沒有找到鍵值為 1的元素\n"; 73 /*運行結果 74 找到鍵值為 12的元素 75 沒有找到鍵值為 1的元素 76 */ 77 78 /*元素的刪除*/ 79 //要想刪除等於某個鍵值時,使用erase()方法 80 cout<<"刪除前:\n"; 81 print(s); 82 s.erase(6);//刪除鍵值為6這個元素 83 cout<<"刪除后:\n"; 84 print(s); 85 /*運行結果 86 刪除前: 87 1 6 8 12 88 刪除后: 89 1 8 12 90 */ 91 92 //要想清空集合 93 cout<<"清空前:\n"; 94 print(s); 95 s.clear(); 96 cout<<"清空后:\n"; 97 print(s); 98 /*運行結果 99 清空前: 100 1 8 12 101 清空后: 102 103 */ 104 105 /*注意使用insert()將元素插入到集合中去的時候,集合會根據設定的比較函數將元素放到相應的結點上。當沒有制定比較 106 函數的時候采用默認比較函數,即按鍵值由小到大的順序插入*/ 107 108 /*插入時編寫比較函數的兩種方法*/ 109 //如果元素是基本數據類型,見main函數之前的定義方法 110 set<int,myComp> ss; 111 ss.insert(8);//同樣,第一次插入,第二次重復元素不插入 112 ss.insert(1); 113 ss.insert(12); 114 ss.insert(6); 115 116 set<int,myComp>::iterator it2;//定義同元素類型的前向迭代器 117 for(it2=ss.begin(); it2 != ss.end(); it2++){ 118 cout<<*it2<<' '; 119 } 120 cout<<endl; 121 /*運行結果 122 12 8 6 1 123 */ 124 125 //如果元素是結構體,可以將比較函數寫在結構體內,見main函數之前的定義方法 126 set<STUDENT> students; 127 STUDENT someone; 128 someone.name="Jack"; 129 someone.score=80.5; 130 students.insert(someone); 131 132 someone.name="Tomi"; 133 someone.score=57.5; 134 students.insert(someone); 135 136 someone.name="Nacy"; 137 someone.score=60.5; 138 students.insert(someone); 139 140 set<STUDENT>::iterator it3;//定義前向迭代器 141 for(it3=students.begin(); it3 != students.end();it3 ++){ 142 cout<<(*it3).name<<":"<<(*it3).score<<endl; 143 } 144 /*運行結果 145 Jack:80.5 146 Nacy:60.5 147 Tomi:57.5 148 */ 149 return 0; 150 } 151 152 void print(set<int> s) 153 { 154 set<int>::iterator it;//定義前向迭代器 155 for(it=s.begin(); it != s.end(); it++){ 156 cout<<*it<<' '; 157 } 158 cout<<endl; 159 } 160 161 void rprint(set<int> s) 162 { 163 set<int>::reverse_iterator rit;//定義反向迭代器 164 for(rit=s.rbegin(); rit != s.rend();rit++){ 165 cout<<*rit<<' '; 166 } 167 cout<<endl; 168 }
