1. 程式人生 > >C++ set學習筆記

C++ set學習筆記

all pri cto 等於 中序 center type 節點 begin

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會根據特定的排序準則,自動將元素進行排序。不同的是後者允許元素重復而前者不允許。

不能直接改變元素值。因為這樣會打亂原有的順序。

改變元素值的方法是:先刪除舊元素,再插入新元素。

存取元素只能通過叠代器,從叠代器的角度看,元素值是常數。

  1. #include <iostream>
  2. #include <set>
  3. using namespace std;
  4. 程序運行會報錯。但是如果把s1的排序準則也指定為greater<int>便運行成功
  5. int main()
  6. {
  7. set<int> s1;
  8. set<int,greater<int> > s2;
  9. for (int i = 1;i < 6;++i)
  10. {
  11. s1.insert(i);
  12. s2.insert(i);
  13. }
  14. if(s1 == s2)
  15. cout << "c1 equals c2 !" << endl;
  16. else
  17. cout << "c1 not equals c2 !" << endl;
  18. }
  19. //此處分割線--------------------------------------------------------------------------------------
  20. set 的幾種操作
  21. set_union(a.begin(),a.end(),b.begin(),b.end(),inserter(c,c.begin()));
  22. cout << "A u B = {";
  23. print(c);
  24. c.clear();
  25. set_intersection(a.begin(),a.end(),b.begin(),b.end(),inserter(c,c.begin()));
  26. cout << "A n B = {";
  27. print(c);
  28. c.clear();
  29. set_difference(a.begin(),a.end(),b.begin(),b.end(),inserter(c,c.begin()));
  30. cout << "A - B = {";
  31. print(c);
  32. c.clear();
  33. set_difference(b.begin(),b.end(),a.begin(),a.end(),inserter(c,c.begin()));
  34. cout << "SA = {";
  35. print(c);
  36. c.clear();
  37. set_difference(a.begin(),a.end(),b.begin(),b.end(),inserter(c,c.begin()));
  38. cout << "SB = {";
  39. print(c)

C++ set學習筆記