set/multiset容器
一、二叉树基本概念
二叉树就是任何节点最多只允许有两个子节点。分别是左子节点和右子节点。
二叉搜索树,是指二叉树中的节点按照一定的规则进行排序,使得对二叉树中元素访问更加高效。二叉搜索树的放置规则是:任何节点的元素值一定大于其左子树中的每一个节点的元素值,并且小于右子树的值。因此从根节点一直向左走,一直到无路可走,即得到最小值,一直向右走,直到无路可走,可得到最大值。那么在二叉搜索树中找到最大元素和最小元素是非常简单的事情。
RB-tree(红黑树)为二叉树的一种。
二、set/multiset特性
set/multiset的特性是所有元素会根据元素的值自动进行排序。set以RB-tree(红黑树,平衡二叉树的一种)为底层机制,其查找效率非常好。set容器中不允许重复元素,multiset允许重复元素。
问:可以通过set的迭代器改变元素的值吗?
答:不行,因为set集合是根据元素值进行排序,关系到set的排序规则,如果任意改变set的话,会严重破坏set组织。
三、set常用API
1、set构造函数
2、set赋值操作
3、set大小操作
4、set插入和删除操作
5、set查找操作
四、案例
程序运行不成功,还未找到原因!
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <set> using namespace std; void PrintSet(set<int>& s) { for (set<int>::iterator it = s.begin();it != s.end();it++) { cout << *it << " "; } cout << endl; } void test01() { //set初始化操作 set<int> s1; s1.insert(7); s1.insert(2); s1.insert(4); s1.insert(5); s1.insert(1); PrintSet(s1);//1 2 4 5 7 //自动进行排序 默认从小到大 //赋值操作 set<int> s2; s2 = s1; PrintSet(s2);//1 2 4 5 7 //删除操作 s1.erase(s1.begin()); PrintSet(s1);//2 4 5 7 s1.erase(7); PrintSet(s1);//2 4 5 } //set查找操作 void test02() { set<int> s1; s1.insert(7); s1.insert(2); s1.insert(4); s1.insert(5); s1.insert(1); set<int>::iterator ret = s1.find(14); if (ret == s1.end()) { cout << "没有找到!" << endl;//没有找到! } else { cout << "ret:" << *ret << endl; } //找到第一个大于等于key的元素 ret = s1.lower_bound(2); if (ret == s1.end()) { cout << "没有找到!" << endl; } else { cout << "ret:" << *ret << endl;//ret:2 } //找到第一个大于key的元素 ret = s1.upper_bound(2); if (ret == s1.end()) { cout << "没有找到!" << endl; } else { cout << "ret:" << *ret << endl;//ret:4 } //equal_range 返回lower_bound和upper_bound的值 pair<set<int>::iterator, set<int>::iterator> myret = s1.equal_range(2); if (myret.first == s1.end()) { cout << "没有找到!" << endl; } else { cout << "myret:" << *(myret.first) << endl;//myret:2 } if (myret.second == s1.end()) { cout << "没有找到!" << endl; } else { cout << "myret:" << *(myret.second) << endl;//myret:4 } } int main(void) { //test01(); test02(); return 0; }
五、set容器存储对象 更改默认排序
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <set> using namespace std; //仿函数 class mycompare { public: bool operator()(int v1, int v2) { return v1 > v2; } }; void test01() { //set初始化操作 set<int, mycompare> s1; s1.insert(7); s1.insert(2); s1.insert(4); s1.insert(5); s1.insert(1); for (set<int>::iterator it = s1.begin();it != s1.end();it++) { cout << *it << " "; } cout << endl; } class Person { public: Person(int age,int id):id(id),age(age){} public: int id; int age; }; //仿函数 class mycompare2 { public: bool operator()(Person p1, Person p2) { return p1.age > p2.age; } }; void test02() { set<Person,mycompare2> sp; Person p1(10, 20), p2(30, 40), p3(50, 60); sp.insert(p1); sp.insert(p2); sp.insert(p3); Person p4(10, 30); for (set<Person, mycompare2>::iterator it = sp.begin();it != sp.end();it++) { cout << (*it).age << " " << (*it).id << endl; } //查找 set<Person, mycompare2>::iterator ret = sp.find(p4); if (ret == sp.end()) { cout << "没有找到!" << endl; } else { cout << "找到:" << (*ret).id << " " << (*ret).age << endl; } } int main(void) { //test01(); test02(); return 0; }