参考 https://en.wikipedia.org/wiki/Red%E2%80%93black_tree
a red–black tree is a kind of self-balancing binary search tree. Each node stores an extra bit representing color, used to ensure that the tree remains approximately balanced during insertions and deletions
红黑树,自平衡二叉树。每个节点相对普通二叉树需要多一bit来存储颜色,事实上几乎没有什么额外的内存开销。
插入(删除),查找都是O(logn)
相比hash表为底层的O(1)自然是差了点,但是人家能排序啊
自平衡(左旋,右旋,变色)看完就忘,以后再说吧
--------------------------
C++ 中set基于rb-tree
参考https://en.cppreference.com/w/cpp/container/set/set
各种初始化方法 (默认,迭代器,复制,列表)
以及一个定制的compare方法。注意最后插入{1,-1}并没有成功,因为从大小度量上来讲,{1,-1}和{1,1}是相等的
源于https://en.cppreference.com/w/cpp/container/multiset
Everywhere the standard library uses the Compare requirements, equivalence is determined by using the equivalence relation as described on Compare
#include <iostream>
#include <string>
#include <set>
#include <cmath>
struct Point { double x, y; };
struct PointCmp {
bool operator()(const Point& lhs, const Point& rhs) const {
return std::hypot(lhs.x, lhs.y) < std::hypot(rhs.x, rhs.y);
}
};
int main()
{
// (1) Default constructor
std::set<std::string> a;
a.insert("cat");
a.insert("dog");
a.insert("horse");
for(auto& str: a) std::cout << str << ' ';
std::cout << '\n';
// (2) Iterator constructor
std::set<std::string> b(a.find("dog"), a.end());
for(auto& str: b) std::cout << str << ' ';
std::cout << '\n';
// (3) Copy constructor
std::set<std::string> c(a);
c.insert("another horse");
for(auto& str: c) std::cout << str << ' ';
std::cout << '\n';
// (4) Move constructor
std::set<std::string> d(std::move(a));
for(auto& str: d) std::cout << str << ' ';
std::cout << '\n';
std::cout << "moved-from set is ";
for(auto& str: a) std::cout << str << ' ';
std::cout << '\n';
// (5) Initializer list constructor
std::set<std::string> e {"one", "two", "three", "five", "eight"};
for(auto& str: e) std::cout << str << ' ';
std::cout << '\n';
// custom comparison
std::set<Point, PointCmp> z = {{2, 5}, {3, 4}, {1, 1}};
z.insert({1, -1}); // this fails because the magnitude of 1,-1 equals 1,1
for(auto& p: z) std::cout << '(' << p.x << ',' << p.y << ") ";
std::cout << '\n';
}
--------------------------
multiset
允许重复元素罢了