说道set/multiset容器,就不得不说二叉树了。
二叉树:二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
平衡二叉树:又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。 最小二叉平衡树的节点总数的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci(斐波那契)数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。
平衡二叉搜索树:(Self-balancing binary search tree)平衡二叉搜索树的任何结点的左子树和右子树高度最多。
Set/multiset容器
1.都是基于二叉树搜索树,也可以说是基于平衡二叉树,也可以说是基于红黑树(平衡二叉树的一种)。
2.内部已经有规则了,所以说是关联式容器。
3.两者的特性是所有元素会根据元素的值自动排序。以红黑树为底层机制。
4.set中不允许两个元素有相同的键值,而multiset允许有相同的键值,这是区分两者的依据。
5.提供迭代器,
#include <iostream>
#include <set> //set和multiset都是一个头文件
#include <string>
using namespace std;
//仿函数
class mycompare
{
public:
bool operator()(int val1, int val2)
{
return val1 > val2;
}
};
void printset(set<int,mycompare> &s)
{
for (auto iter = s.begin(); iter != s.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
}
bool comp(int val1, int val2)
{
return val1 > val2;
}
//set容器的初始化
void test01()
{
std::set<int,mycompare> s; //自动进行排序,默认从小到大,后面的必须是类型
s.insert(7);
s.insert(9);
s.insert(1);
s.insert(4);
s.insert(10);
printset(s);
//有先序遍历,中序,后序
//如何改变默认排序
#if 0
//赋值
set<int> s2;
s2 = s;
//删除操作
s.erase(s.begin());
printset(s);
s.erase(10);
printset(s);
#endif
}
//查找
void test02()
{
std::set<int> s;
s.insert(7);
s.insert(9);
s.insert(1);
s.insert(4);
s.insert(10);
auto ret = s.find(4); //返回的是迭代器
if (ret == s.end())
cout << "no elem";
cout << *ret << endl;
//lower_bound(keyElem);//返回第一个 key >= keyElem 元素的迭代器
s.lower_bound(2);
//找到第一个大于等于key的元素
auto ret2 = s.find(4); //返回的是迭代器
if (ret2 == s.end())
cout << "no elem" << endl;
cout << *ret << endl;
cout << " ======================" << endl;
//找到第一个大于key的值
auto i = s.upper_bound(4);
cout << *i << endl;
//equal_range 返回lower_bound和upper_bound值
s.equal_range(4);
pair<set<int>::iterator, set<int>::iterator> myset = s.equal_range(4);
//auto myset = s.equal_range(4); //等于上面
if (myset.first == s.end())
{
cout << "没有找到" << endl;
}
else
{
cout << "myset.first: " << *(myset.first) << endl;
}
if (myset.second == s.end())
{
cout << "没有找到" << endl;
}
else
{
cout << "myset.second: " << *(myset.second) << endl;
}
}
void test03()
{
//第一种,构造方法
pair<int, int> p(10, 20);
cout << p.first << " " << p.second << endl;
//第二种
pair<string, int> p2 = make_pair("name", 23);
cout << p2.first << " " << p2.second << endl;
//第三种
pair<string, int> p3 = p2;
cout << p3.first << " " << p3.second << endl;
}
//存储对象
class Person
{
public:
Person(int id, int age) :_id(id), _age(age) {}
public:
int _id;
int _age;
};
class mycompare2
{
public:
bool operator()(const Person& p1, const Person& p2) //排序要返回bool ,这里不用引用
{
return p1._id > p2._id;
}
};
void test04()
{
set<Person, mycompare2> sp; //set需要默认排序的,需要自己定义排序规则
Person p1(10, 10), p2(20, 20), p3(30, 30), p4(40, 40);
sp.insert(p1);
sp.insert(p2);
sp.insert(p3);
sp.insert(p4);
for (auto iter = sp.begin(); iter != sp.end(); iter++)
{
cout << (*iter)._id << " " << (*iter)._age << endl;
}
//查找 find()
//这里就根据自定义的规则查找,这里是根据id查找的,返回迭代器
//auto temp = sp.find(p1); //这里一直不通过...
}
int main()
{
//test01();
test04();
system("pause");
return 0;
}