/*
*
********************************************
* set集合容器的基础说明:
********************************************
*
* set集合容器使用RB-Tree的平衡二叉检索树的数据结构,不允许插入重复键值
* 每个子树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的所有键值
* 插入过程中要进行平衡处理,但检索过程效率高
*
* 提供了元素插入、删除、检索的功能
* Unique Sorted Associative Container Simple Associative Container
*
* 使用set必须使用宏语句#include <set>
*
**************************************************************************************
*
* 创建set对象:
* 1.set<int> a;
* 2.set(const key_compare& comp) //指定一个比较函数对象comp来创建set对象
*
* srtuct strLess{
* bool operator()(const char* s1,const char* s2) const{
* return strcmp(s1,s2)<0;
* }
* };
* set<const char*,strLess> s(strLess());
*
* 3.set(const set&); //set<int> b(a);
* 4.set(first,last); //set<char> c(a.begin(),a.end())
* 5.set(first,last,const key_compare& comp);
**************************************************************************************
*
* 元素的插入 //不允许插入重复键值
* pair<iterator,bool> insert(const value_type& v); //可用于判断是否重复插入元素,对于特殊的信息可以提供这样的判断
* iterator insert(iterator pos,const value_type& v);
* void insert(first,last);
*
**************************************************************************************
*
* 元素的删除
* void erase(iterator pos);
* size_type erase(const key_type& k); //删除等于键值k的元素
* void erase(first,last); //删除[first,last)区间的元素
* void clear();
*
**************************************************************************************
*
* 访问与搜索
*
* iterator begin();iterator end();
* reverse_iterator rbegin();reverse_iterator rend();
*
* iterator find(const key_type& k) const;
*
* 其它常用函数
* bool empty() const;
* size_type size() const;
* void swap();
*
* //下面三个函数还没找到合适的例子,故不做说明
* iterator lower_bound();iterator upper_bound();pair<iterator,iterator> equal_range();//上界、下届、确定区间
*
*
*
********************************************
** cumirror ** [email protected] ** **
********************************************
*
*/
#include <set>
#include <iostream>
//自定义数据的插入
struct student{
char name[20];
int age;
char city[20];
char phone[20];
bool operator()(const student& a,const student& b) const{
return strcmp(a.name,b.name)<0;
}
};
int main(){
using namespace std;
set<int> a;
a.insert(10);
a.insert(19);
a.insert(8);
a.insert(102);
a.insert(1);
pair<set<int>::iterator, bool> p=a.insert(18);
if(p.second){
cout<<"插入的新元素为:"<<*(p.first)<<endl;
}
else{
cout<<"已存在该元素,重复插入"<<endl;
}
set<int>::iterator i=a.find(8);
// *i=250; //与侯捷STL源码剖析237页所述有出入
cout<<*i<<endl; //原文为:企图通过迭代器改变元素是不被允许的
// a.insert(251); //但VC6.0编译运行没有问题,只是set中的排序不正确了
//即使重新插入251,因没有违反红黑树标准,错误不被修正
//是否是因为STL版本问题:换STLport后编译果然报错
//vc6.0中的STL库存在一定问题,大家注意
cout<<"元素访问:"<<endl;
for(set<int>::iterator j=a.begin();j!=a.end();j++){
cout<<*j<<endl;
}
// 为何称为容器,我认为在于对于用户自定义数据的包容,故写如下例子进行测试验证
// 也可以尝试用age作为判断条件
student stu1={"童进",23,"武汉","XXX"};
student stu2={"老大",28,"武汉","XXX"}; //老大,你成熟了5岁,哈哈
student stu3={"饺子",23,"武汉","XXX"};
set<student,student> b(student());
b.insert(stu1);
b.insert(stu2);
b.insert(stu3);
student stu4={"饺子123",88,"福州","XXX"};
pair<set<student,student>::iterator,bool> query=b.insert(stu4);
if(query.second==false) //query.first返回插入元素的迭代器;query.second代表插入是否成功,true成功:false失败
cout<<"重复元素插入会失败"<<endl;
cout<<query.first->name<<endl;
for(set<student,student>::iterator k=b.begin();k!=b.end();k++){
cout<<k->name<<endl;
}
// student test1={"老大",23,"武汉","XXX"}; //这样的元素,可以找到
// set<student,student>::iterator v=b.find(test1);
// student test2={"",23,"武汉","XXX"}; //无法找到
// set<student,student>::iterator v=b.find(test2);
student test3={"老大",99,"",""}; //可以找到,推测:
set<student,student>::iterator v=b.find(test3); //1.键值的设定依据key_compare()函数中的设置
cout<<v->age<<endl; //2.键值直接为定义数据类型中的第一个元素
//结论:推测1正确。
//可以修改operator()函数进行验证,也可以看后续multiset中的例子
return 0;
}