set集合容器
set集合容器实现了红黑树(Red-BlackTree)的平衡二叉检索树的数据结构,在插入元素时,它会自动调整二叉树,把该元素放到适当的位置,以确保每个子树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值;另外,确保左右子树的高度相等,这样,二叉树的高度最小,从而检索速度最快。【不会重复插入相同键值的元素,采取忽略处理】
平衡二叉检索树使用中序遍历算法,检索效率高于vector、deque和list等容器。另外,采用中序遍历算法可将键值由小到大遍历出来。(使用set前,头文件包含声明“#include <set>”)
- 创建set集合对象,指定元素类型:set<int> s;
- 元素插入与中序遍历:
#include <set> #include <iostream> using namespace std; int main(int argc,char* argv[]) { set<int> s; //插入5个元素,8由于重复,第二次插入的8没有执行 s.insert(8); s.insert(1); s.insert(12); s.insert(6); s.insert(8); //中序遍历集合中的元素 set<int>::iterator it;//定义前向迭代器 for(it=s.begin();it!=s.end();it++) cout<<*it<<" "; cout<<endl; return 0; }
运行结果:1 6 8 12 - 元素反向遍历:
#include <set> #include <iostream> using namespace std; int main(int argc,char* argv[]) { set<int> s; //插入5个元素,8由于重复,第二次插入的8没有执行 s.insert(8); s.insert(1); s.insert(12); s.insert(6); s.insert(8); //中序遍历集合中的元素 set<int>::reverse_iterator rit;//定义反向迭代器 for(rit=s.begin();rit!=s.end();rit++) cout<<*rit<<" "; cout<<endl; return 0; }
运行结果:12 8 6 1 - 元素的删除:删除的对象可以是某个迭代器位置上的元素、等于某键值的元素、一个区间上的元素和清空元素
#include <set> #include <iostream> using namespace std; int main(int argc,char* argv[]) { set<int> s; //插入5个元素,8由于重复,第二次插入的8没有执行 s.insert(8); s.insert(1); s.insert(12); s.insert(6); s.insert(8); //删除键值为6的那个元素 s.erase(6); //反向遍历集合中的元素 set<int>::reverse_iterator rit;//定义反向迭代器 for(rit=s.begin();rit!=s.end();rit++) cout<<*rit<<" "; cout<<endl; //清空集合 s.clear(); //输出集合大小,应为0 cout<<s.size()<<endl; return 0; } //运行结果: //12 8 1 //0
- 元素检索:
#include <set> #include <iostream> using namespace std; int main(int argc,char* argv[]) { set<int> s; //插入5个元素,8由于重复,第二次插入的8没有执行 s.insert(8); s.insert(1); s.insert(12); s.insert(6); s.insert(8); set<int>::iterator it;//定义前向迭代器 //查找键值为6的那个元素 it=s.find(6); if(it!=s.end())//找到 cout<<*it<<endl; else//没找到 cout<<"not find it"<<endl it=s.find(20); if(it!=s.end())//找到 cout<<*it<<endl; else//没找到 cout<<"not find it"<<endl return 0; } //运行结果: //6 //not find it
- 自定义比较函数:
- 元素不为结构体时:下面编写的比较规则为要求按键值由大到小的顺序插入:
#include <set> #include <iostream> using namespace std; //自定义比较函数myComp,重载“()”操作符 struct myComp { bool operator() (const int &a,const int &b) { return a>b; } }; int main(int argc,char* argv[]) { set<int,myComp> s; //插入5个元素,8由于重复,第二次插入的8没有执行 s.insert(8); s.insert(1); s.insert(12); s.insert(6); s.insert(8); set<int,myComp>::iterator it;//定义前向迭代器 for(it=s.begin();it!=s.end();it++) cout<<*it<<" "; cout<<endl; return 0; } //运行结果: //12 8 6 1
- 元素为结构体时,可以直接把比较函数写在结构体内:
#include <set> #include <iostream> using namespace std; struct Info { string name; float score; //重载"<"操作符,自定义排序规则 bool operator < (const Info &a) const { //按score由大到小排序。如果由小到大,使用">"即可 return a.score<score; } }; }; int main(int argc,char* argv[]) { set<Info> s; Info info;//定义Info类型的元素 info.name="Jack"; info.score=80.5; s.insert(info); info.name="Tomi"; info.score=20.5; s.insert(info); info.name="Nacy"; info.score=60.5; s.insert(info); set<Info>::iterator it;//定义前向迭代器 for(it=s.begin();it!=s.end();it++) cout<<(*it).name<<" : "<<(*it).score<<endl; return 0; } //运行结果: //Jack : 80.5 //Nacy : 60.5 //Tomi : 20.5