C++ set學習筆記
Stl~(multi)set
set集合容器:實現了紅黑樹的平衡二叉檢索樹的數據結構,插入元素時,它會自動調整二叉樹的排列,把元素放到適當的位置,以保證每個子樹根節點鍵值大於左子樹所有節點的鍵值,小於右子樹所有節點的鍵值;另外,還得保證根節點左子樹的高度與右子樹高度相等
在set中每個元素的值都唯一,而且系統能根據元素的值自動進行排序。應該註意的是set中數元素的值不能直接被改變。C++ STL中標準關聯容器set, multiset, map, multimap內部采用的就是一種非常高效的平衡檢索二叉樹:紅黑樹,也成為RB樹(Red-Black Tree)。RB樹的統計性能要好於一般平衡二叉樹,所以被STL選擇作為了關聯容器的內部結構。
常用操作:
begin() 返回指向第一個元素的叠代器
clear() 清除所有元素
count() 返回某個值元素的個數,多用於存在性判斷,值只能是0或1
empty() 如果集合為空,返回true
end() 返回指向最後一個元素的叠代器
equal_range() 返回集合中與給定值相等的上下限的兩個叠代器
erase() 刪除集合中的元素
find() 返回一個指向被查找到元素的叠代器
get_allocator() 返回集合的分配器
insert() 在集合中插入元素
lower_bound() 返回指向大於(或等於)某值的第一個元素的叠代器
key_comp() 返回一個用於元素間值比較的函數
max_size() 返回集合能容納的元素的最大限值
rbegin() 返回指向集合中最後一個元素的反向叠代器
rend() 返回指向集合中第一個元素的反向叠代器
size() 集合中元素的數目
swap() 交換兩個集合變量
upper_bound() 返回大於某個值元素的叠代器
value_comp() 返回一個用於比較元素間的值的函數
1.元素插入:insert()
insert(key_value); 將key_value插入到set中 ,返回值是pair<set<int>::iterator,bool>,bool標誌著插入是否成功,而iterator代表插入的位置,若key_value已經在set中,則iterator表示的key_value在set中的位置。
if(pr.second)
{
cout<<*pr.first<<endl;
}
inset(first,second);將定位器first到second之間的元素插入到set中,返回值是void.
2.中序遍歷:類似vector遍歷(用叠代器)
3.反向遍歷:利用反向叠代器reverse_iterator。
例:
set<int> s;
......
set<int>::reverse_iterator rit;
for(rit=s.rbegin();rit!=s.rend();rit++)
4.元素刪除:與插入一樣,可以高效的刪除,並自動調整使紅黑樹平衡。
set<int> s;
s.erase(2); //刪除鍵值為2的元素
s.clear();
erase(iterator) ,刪除定位器iterator指向的值
erase(first,second),刪除定位器first和second之間的值
erase(key_value),刪除鍵值key_value的值
5.元素檢索:find(),若找到,返回該鍵值叠代器的位置,否則,返回最後一個元素後面一個位置。
set<int> s;
set<int>::iterator it;
it=s.find(5); //查找鍵值為5的元素
if(it!=s.end()) //找到
cout<<*it<<endl;
else
//未找到
cout<<"未找到";
lower_bound(key_value) ,返回第一個大於等於key_value的定位器
upper_bound(key_value),返回最後一個大於等於key_value的定位器
6.自定義比較函數
(1)元素不是結構體:
例:
//自定義比較函數myComp,重載“()”操作符
struct
myComp
{
bool operator()(const your_type &a,const your_type
&b)
[
return a.data-b.data>0;
}
}
set<int,myComp>s;
......
set<int,myComp>::iterator it;
(2)如果元素是結構體,可以直接將比較函數寫在結構體內。
例:
struct
Info
{
string name;
float score;
//重載“<”操作符,自定義排序規則
bool operator < (const Info &a) const
{
//按score從大到小排列
return a.score<score;
}
}
set<Info> s;
......
set<Info>::iterator it;
count() 用來查找set中某個某個鍵值出現的次數。這個函數在set並不是很實用,因為一個鍵值在set只可能出現0或1次,這樣就變成了判斷某一鍵值是否在set出現過了
set和multiset會根據特定的排序準則,自動將元素進行排序。不同的是後者允許元素重復而前者不允許。
不能直接改變元素值。因為這樣會打亂原有的順序。
改變元素值的方法是:先刪除舊元素,再插入新元素。
存取元素只能通過叠代器,從叠代器的角度看,元素值是常數。
- #include <iostream>
- #include <set>
- using namespace std;
- 程序運行會報錯。但是如果把s1的排序準則也指定為greater<int>便運行成功
- int main()
- {
- set<int> s1;
- set<int,greater<int> > s2;
- for (int i = 1;i < 6;++i)
- {
- s1.insert(i);
- s2.insert(i);
- }
- if(s1 == s2)
- cout << "c1 equals c2 !" << endl;
- else
- cout << "c1 not equals c2 !" << endl;
- }
- //此處分割線--------------------------------------------------------------------------------------
- set 的幾種操作
- set_union(a.begin(),a.end(),b.begin(),b.end(),inserter(c,c.begin()));
- cout << "A u B = {";
- print(c);
- c.clear();
- set_intersection(a.begin(),a.end(),b.begin(),b.end(),inserter(c,c.begin()));
- cout << "A n B = {";
- print(c);
- c.clear();
- set_difference(a.begin(),a.end(),b.begin(),b.end(),inserter(c,c.begin()));
- cout << "A - B = {";
- print(c);
- c.clear();
- set_difference(b.begin(),b.end(),a.begin(),a.end(),inserter(c,c.begin()));
- cout << "SA = {";
- print(c);
- c.clear();
- set_difference(a.begin(),a.end(),b.begin(),b.end(),inserter(c,c.begin()));
- cout << "SB = {";
- print(c)
C++ set學習筆記