目录
8. std::multiset 跟set接口一样,只是允许冗余,不去重
①map是C++98中已存在的,unordered_map是C++11中才有的
②map中都重载了[]运算符,multimap中没有重载[]运算符,set也没有重载[]。
③map中key不能修改,因为如果修改了就不能保证红黑树的有序特性了
①set中也可以存储键值对,实例化set时,将set中元素类型设置为pair即可
②set默认是升序,但是其内部默认不是按照大于比较,而是按照 less小于比较
3.insert写法提高 记录水果次数 的效率(不这么写,只是为[]做铺垫)
(3)做法三:sort 非稳定排序,可以控制比较方法使其稳定
set 是一个K模型的搜索二叉树 #include
(1)和(2)相当于一样,在pos位置插入也会自动排序
insert :排序 + 去重
- void test_set1()
- {
- set<int> s;
- s.insert(4);
- s.insert(5);
- s.insert(2);
- s.insert(1);
- s.insert(1);
- s.insert(3);
- s.insert(2);
- s.insert(1);
-
-
- // 排序 + 去重
- set<int>::iterator it = s.begin();
- while (it != s.end())
- {
- //*it = 10; 迭代器不支持修改
- cout << *it << " ";
- ++it;
- }
- cout << endl;
-
- for (auto e : s)
- {
- cout << e << " ";
- }
- cout << endl;
- }
能找到就返回元素的迭代器,找不到就返回end
set::find 搜索二叉树特性查找,时间复杂度是O(logN)
全局的find 是暴力查找,时间复杂度是O(N)
所以set::find效率更高
- void test_set2()
- {
- set<int> s;
- s.insert(4);
- s.insert(5);
- s.insert(2);
- s.insert(1);
- s.insert(1);
- s.insert(3);
- s.insert(2);
- s.insert(1);
-
- set<int>::iterator pos = s.find(20); // O(logN)
- if (pos != s.end())
- {
- cout << "set.find找到了" << endl;
- }
-
- pos = find(s.begin(), s.end(), 2); // O(N)
- if (pos != s.end())
- {
- cout << "find找到了" << endl;
- }
- }
size_type就是size_t,也就是unsigned int
(1) void erase (iterator position); 必须加检查if (pos != s.end()) s.erase(pos); 因为有pos时,正常运行,如果没有pos,就会报错。例如:s.erase(pos);
(2)size_ type erase (const value_ type& val) ; 则可以随便删,无论有没有都不报错 例如:s.erase(3)
(3)void erase (iterator first,iterator last) 删的是[ first, last),即不包含 last
- void test_set3()
- {
- set<int> s;
- s.insert(4);
- s.insert(5);
- s.insert(2);
- s.insert(1);
- s.insert(1);
- s.insert(3);
- s.insert(2);
- s.insert(1);
-
- cout << s.erase(3) << endl; //有就返回1
- cout << s.erase(30) << endl; //没有就返回0
-
- for (auto e : s)
- {
- cout << e << " ";
- }
- cout << endl;
-
- set<int>::iterator pos = s.find(3);
- if (pos != s.end())
- s.erase(pos);
-
- for (auto e : s)
- {
- cout << e << " ";
- }
- cout << endl;
-
- if (s.count(5))
- {
- cout << "5在" << endl;
- }
-
- if (s.find(5) != s.end())
- {
- cout << "5在" << endl;
- }
打印:
5在
5在
返回>= val得位置迭代器 3返回3位置 6 返回7位置
- 返回>= val的位置迭代器 3返回3位置 6 返回7位置
- set<int> s;
- s.insert(4);
- s.insert(5);
- s.insert(1);
- s.insert(3);
- s.insert(2);
- s.insert(7);
- s.insert(9);
- set<int>::iterator lowIt = s.lower_bound(3); 存在
- lowIt = s.lower_bound(6); 不存在
- void test_set4()
- {
- set<int> s;
- s.insert(4);
- s.insert(5);
- s.insert(1);
- s.insert(3);
- s.insert(2);
- s.insert(7);
- s.insert(9);
- for (auto e : s)
- {
- cout << e << " ";
- }
- cout << endl;
-
- // 要求删除>=x的所有值
- int x;
- cin >> x;
- set<int>::iterator lowIt = s.lower_bound(x);
- s.erase(lowIt, s.end());
-
- for (auto e : s)
- {
- cout << e << " ";
- }
- cout << endl;
- }
返回>x位置的迭代器,s.upper_bound(5) 存在5,不存在6,则返回7;s.upper_bound(6) 不存在6,返回7;
- set<int> s;
- s.insert(4);
- s.insert(5);
- s.insert(1);
- s.insert(3);
- s.insert(2);
- s.insert(7);
- s.insert(9);
-
- 返回>x位置的迭代器 -》 都是返回 7位置的迭代器
- set<int>::iterator upIt = s.upper_bound(5); // 存在
- upIt = s.upper_bound(6); // 不存在
用途:例如 删除x <= <= y的区间 删除 [x,y]
- void test_set4()
- {
- set<int> s;
- s.insert(4);
- s.insert(5);
- s.insert(1);
- s.insert(3);
- s.insert(2);
- s.insert(7);
- s.insert(8);
-
- // 返回>= val得位置迭代器 3返回3位置 6 返回7位置
- /*set
::iterator lowIt = s.lower_bound(3); 存在 - lowIt = s.lower_bound(6); 不存在*/
- for (auto e : s)
- {
- cout << e << " ";
- }
- cout << endl;
-
- // 删除x <= <= y的区间 删除 [x,y]
- int x, y;
- cin >> x >> y;
- auto leftIt = s.lower_bound(x); // [
- auto rightIt = s.upper_bound(y); // )
- s.erase(leftIt, rightIt);
- for (auto e : s)
- {
- cout << e << " ";
- }
- cout << endl;
- }
插入重复的数时set会去重,multiset不去重,允许冗余
不同:
multiset 的count和erase 返回查找或删除个数
find(x) 多个x的话,find返回中序第一个x
- void test_set6()
- {
- multiset<int> s;
- s.insert(4);
- s.insert(5);
- s.insert(2);
- s.insert(1);
- s.insert(1);
- s.insert(3);
- s.insert(2);
- s.insert(1);
- s.insert(3);
- s.insert(3);
- s.insert(3);
- s.insert(3);
-
- // 排序
- set<int>::iterator it = s.begin(); //迭代器打印
- while (it != s.end())
- {
- //*it = 10;
- cout << *it << " ";
- ++it;
- }
- cout << endl;
-
- for (auto e : s) //范围for打印
- {
- cout << e << " ";
- }
- cout << endl;
-
- cout << s.count(1) << endl; //测试count,打印3,因为1有3个
- cout << s.erase(1) << endl; //测试erase,打印3,因为1有3个
- for (auto e : s)
- {
- cout << e << " ";
- }
- cout << endl;
-
- auto pos = s.find(3); // 多个x的话,find返回中序第一个x
- while (pos != s.end()) //从中序第一个3开始打印完整个
- {
- cout << *pos << " ";
- ++pos;
- }
- cout << endl;
- }
方法一:把nums1和nums2分别放进s1和s2中进行去重,再利用范围for把s2中的每个元素在s1中进行查找,如果找到就放进v中。时间复杂度是:O(n*logn) n个节点,每个节点找logn高度次
- class Solution {
- public:
- vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
- //去重
- set<int> s1;
- for(auto e:nums1)
- {
- s1.insert(e);
- }
- //去重
- set<int> s2;
- for(auto e:nums2)
- {
- s2.insert(e);
- }
- vector<int> v;
- for(auto e:s2)
- {
- if(s1.count(e))
- {
- v.push_back(e);
- }
- }
- return v;
- }
- };
方法二:
- class Solution {
- public:
- vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
- set<int> s1;
- for(auto e:nums1)
- {
- s1.insert(e);
- }
-
- set<int> s2;
- for(auto e:nums2)
- {
- s2.insert(e);
- }
- vector<int> v;
- set<int>::iterator it1=s1.begin();
- set<int>::iterator it2=s2.begin();
- while(it1!=s1.end() && it2!=s2.end())
- {
- if(*it1>*it2) //相比较,值小的++
- {
- ++it2;
- }
- else if(*it1<*it2) //相比较,值小的++
- {
- ++it1;
- }
- else //相比较,值相等就放进v中,同时++
- {
- v.push_back(*it1);
- ++it1;
- ++it2;
- }
- }
- return v;
- }
- };
map是KV模型的搜索二叉树,insert和[]用法是重点,其他用法参考set #include
原因:map中key是唯一的,每个key都有与之对应的value,经常需要通过key获取value,因此 map为了形象简单 就重载了[]运算符, multimap中key是可以重复的,如果重载了[]运算符,给定 一个key时,就没有办法返回 value了,因此,multimap中没有重载[]运算符
less是把小的放左边,所以是升序;greater是把大的放左边,所以是降序
解释:map和set的底层结构都是红黑树,而红黑树是近似的平衡二叉搜索树,故查询时间 复杂度为O(log_2N)
pair 打包了KV模型的key和val两个类型的值,c++不支持返回两个值,也就不知道返回key和val哪一个了,所以干脆打包key和val,返回一个pair结构
(value_type 是 pair
pair中的first就相当于KV模型中的key,second相当于KV模型中的val
make_pair 相当于返回了一个pair的匿名对象
几种插入英汉字典的方式:匿名对象插入,普通对象插入,make_pair插入
- void test_map1()
- {
- map
dict; -
- // pair构造函数
- dict.insert(pair
("sort", "排序")); //匿名对象插入更便捷 - pair
kv("insert", "插入") ; //普通对象插入 - dict.insert(kv);
-
- // make_pair
- auto ret1 = dict.insert(make_pair("left", "左边")); //make_pair插入
- auto ret2 = dict.insert(make_pair("left", "剩余"));
- // 遍历
- //map
::iterator it = dict.begin(); - auto it = dict.begin();
- while (it != dict.end())
- {
- //cout << *it << " "; // it->operator*()
- //cout << (*it).first << ":" << (*it).second << endl;
- cout << it->first << ":" << it->second << endl;
- ++it;
- }
- cout << endl;
-
- for (const auto& kv : dict)
- {
- cout << kv.first << ":" << kv.second << endl;
- }
- }
-
- int main()
- {
- test_map1();
- return 0;
- }
- void test_map2()
- {
- string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
- map
int> countMap; - for (auto& str : arr)
- {
- map
int>::iterator it = countMap.find(str); - if (it != countMap.end()) //如果countMap中有,就计数加1
- {
- it->second++;
- }
- else
- {
- countMap.insert(make_pair(str, 1)); //没有就插入水果
- }
- }
- for (auto& str : arr)
- {
- countMap[str]++;
- }
- for (const auto& kv : countMap)
- {
- cout << kv.first << ":" << kv.second << endl;
- }
- }
map的insert默认是按照pair中的first进行排序的
- string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
- map
int> countMap; - for (auto& str : arr)
- {
- pair
- //或者 auto ret = countMap.insert(make_pair(str, 1));
- if (ret.second == false)
- {
- ret.first->second++;
- }
- }
- for (const auto& kv : countMap)
- {
- cout << kv.first << ":" << kv.second << endl;
- }
解释:
pair
- void test_map2()
- {
- string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
- map
int> countMap; - for (auto& str : arr)
- {
- countMap[str]++;
- }
-
- for (const auto& kv : countMap)
- {
- cout << kv.first << ":" << kv.second << endl;
- }
- }
解释:
countMap[str]++; 中 countMap[str] 返回的是新插入节点中的 次数second 。
如果插入的str不在 对象countMap中,countMap[str]++; 就是插入这个节点,迭代器就是新节点的迭代器,看原码可知 int类型的次数second用的是缺省值(对应原码中的mapped_typed(),是缺省值 ),所以开始second就是0,++后就是1。作用就是插入并修改val (val意思就是second)。
如果插入的str在 对象countMap中,countMap[str]++; 就是查找到这个节点,迭代器就是已有节点的迭代器,int类型的次数second在第一次已经是1了,++后就是2。作用就是插入并修改val (val意思就是second,用于计水果次数)。
- void test_map1()
- {
- map
dict; -
- // pair构造函数
- dict.insert(pair
("sort", "排序")); - pair
kv("insert", "插入") ; - dict.insert(kv);
-
- // make_pair
- auto ret1 = dict.insert(make_pair("left", "左边"));
- auto ret2 = dict.insert(make_pair("left", "剩余"));
-
- dict["operator"] = "重载"; // 插入+修改
- dict["left"] = "左边、剩余"; // 修改
- dict["erase"]; // 插入
- cout << dict["left"] << endl; // 查找
- }
相比map,multimap使用函数接口最大的区别是什么?
答:不支持operator[] 。
把map中的pair放到v中再用stable_sort稳定排序,再把各个pair对应的first放到vv中,再输出vv
- class Solution {
- public:
- typedef map
int>::iterator CountIter; - struct less
- {
- bool operator()(const pair
int >& x,const pairint >& y) - {
- return x.second>y.second;
- }
- };
-
- vector
topKFrequent(vector& words, int k) { - map
int> countMap; - for(auto& str:words)
- {
- countMap[str]++;
- }
-
- vector
int>> v; - CountIter it=countMap.begin();
- while(it!=countMap.end())
- {
- //cout<
first<<" "<second< - v.push_back(*it);
- ++it;
- }
-
- stable_sort(v.begin(),v.end(),less()); //stable_sort稳定排序
- vector
vv; - for(int i=0;i
- {
- vv.push_back(v[i].first);
- }
- for(auto e:v)
- {
- cout<
" "< - }
- return vv;
- }
- };
(2)做法二:stable_sort稳定排序 2
与做法一不同的是:pair很大,为了减少拷贝,我们可以选择不拷贝pair而是拷贝迭代器,把map中的迭代器放到v中,比较方法中通过迭代器找到second,再用stable_sort稳定排序这些迭代器,再把各个迭代器对应的first放到vv中,再输出vv
自己敲的:
- class Solution {
- public:
- typedef map
int>::iterator CountIter; - struct less //降序
- {
- bool operator()(const CountIter& x,const CountIter& y)
- {
- return x->second > y->second;
- }
- };
-
- vector
topKFrequent(vector& words, int k) { - map
int> countMap; - for(auto& str:words)
- {
- countMap[str]++;
- }
-
- vector
v; - CountIter it=countMap.begin();
- while(it!=countMap.end())
- {
- //cout<
first<<" "<second< - v.push_back(it);
- ++it;
- }
-
- stable_sort(v.begin(),v.end(),less()); //stable_sort稳定排序
- for(auto e:v)
- {
- cout<
first<<" "<second< - }
- vector
vv; - for(int i=0;i
- {
- vv.push_back(v[i]->first);
- }
-
- return vv;
- }
- };
(3)做法三:sort 非稳定排序,可以控制比较方法使其稳定
相比较上面的方法,把stable_sort换成sort后,只需要控制比较方法即可使其稳定:因为map中默认是按照分first小的在前排序的,sort 时我们设计的比较方法是按second排序的,但是当second相等时,sort有可能打乱之前map中按 first 排的先后顺序,这样就是不稳定。我们只需要比较方法中让second相等时的情况再按first小的在前排好就可以达到稳定的目的。(相等时会多比一下first,会影响一点效率)
自己敲的:
(4)做法四:利用map自身按照first排序
map的insert默认是按照pair中的first进行排序的,因此我们可以创建一个sortMap,int对应first,string对应second,然后一个一个从kv中插入进sortMap(kv中的first和second颠倒一下插入进去),因为map默认去掉重复的first,这样会导致把次数重复的元素去掉(因为次数放在了first位置),因此要用允许重复的multimap,插入顺序map默认是less降序,因为是top-k问题,我们要把map中插入顺序改成升序插入greater。
- class Solution {
- public:
- vector
topKFrequent(vector& words, int k) { - map
int> countMap; - for(auto& str:words)
- {
- countMap[str]++;
- }
- //排序
- multimap<int,string,greater<int>> sortMap;
- for(auto& kv:countMap)
- {
- sortMap.insert(make_pair(kv.second,kv.first));
- }
- // auto it=sortMap.begin();
- // while(it!=sortMap.end())
- // {
- // cout<
first<<" "<second< - // ++it;
- // }
- vector
vv; - auto it=sortMap.begin();
- for(int i=0;i
- {
- vv.push_back(it->second);
- ++it;
- }
-
- return vv;
- }
- };
官方写法:
四.用红黑树模拟实现map,set
重点:
struct SetKeyOfT 仿函数,用于在RBTree.h找到map/set中所要比较的值,用于控制RBTree.h中pair类型的比较方法,因为库中的pair类型 先比first再比second 的比较方法不是我们想要的
Map.h
- #pragma once
- #include "RBTree.h"
-
- namespace bit
- {
- template<class K, class V>
- class map
- {
- struct MapKeyOfT
- {
- const K& operator()(const pair
& kv) - {
- return kv.first;
- }
- };
- public:
- typedef typename RBTree
, MapKeyOfT>::iterator iterator; - typedef typename RBTree
, MapKeyOfT>::const_iterator const_iterator; -
- iterator begin()
- {
- return _t.Begin();
- }
-
- iterator end()
- {
- return _t.End();
- }
-
- pair
bool > insert(const pair& kv) - {
- return _t.Insert(kv);
- }
-
- iterator find(const K& key)
- {
- return _t.Find(key);
- }
-
- V& operator[](const K& key)
- {
- pair
bool> ret = insert(make_pair(key, V())); - return ret.first->second;
- }
-
- private:
- RBTree
, MapKeyOfT> _t; - };
-
- void test_map1()
- {
- map
int> m; - m.insert(make_pair("111", 1));
- m.insert(make_pair("555", 5));
- m.insert(make_pair("333", 3));
- m.insert(make_pair("222", 2));
-
- map
int>::iterator it = m.begin(); - while (it != m.end())
- {
- cout << it->first << ":" << it->second << endl;
- ++it;
- }
- cout << endl;
-
- for (auto& kv : m)
- {
- cout << kv.first << ":" << kv.second << endl;
- }
- cout << endl;
- }
-
- void test_map2()
- {
- string arr[] = { "ƻ", "", "ƻ", "", "ƻ", "ƻ", "", "ƻ", "㽶", "ƻ", "㽶" };
-
- map
int> countMap; - for (auto& str : arr)
- {
- countMap[str]++;
- }
-
- for (const auto& kv : countMap)
- {
- cout << kv.first << ":" << kv.second << endl;
- }
- }
-
- void test_map3()
- {
- map
dict; - dict["insert"];
- dict["insert"] = "";
- dict["left"] = "";
-
- }
- }
Set.h
- #pragma once
-
- #include "RBTree.h"
-
- namespace bit
- {
- template<class K>
- class set
- {
- struct SetKeyOfT
- {
- const K& operator()(const K& key)
- {
- return key;
- }
- };
- public:
- typedef typename RBTree
::const_iterator iterator; - typedef typename RBTree
::const_iterator const_iterator; -
- iterator begin() const //set内容不想被修改(key值不修改),则给this设置const,
- { //调用时会调用带const的Begin()
- return _t.Begin();
- }
-
- iterator end() const
- {
- return _t.End();
- }
-
- pair
bool > insert(const K& key) - {
- //pair
::iterator, bool> ret = _t.Insert(key); - auto ret = _t.Insert(key);
- return pair
bool>(iterator(ret.first._node), ret.second); - }
-
- iterator find(const K& key)
- {
- return _t.Find(key);
- }
- private:
- RBTree
_t; - };
-
- void test_set1()
- {
- set<int> s;
- s.insert(8);
- s.insert(6);
- s.insert(11);
- s.insert(5);
- s.insert(6);
- s.insert(7);
- s.insert(10);
- s.insert(13);
- s.insert(12);
- s.insert(15);
-
- set<int>::iterator it = s.begin();
- while (it != s.end())
- {
- cout << *it << " ";
- ++it;
- }
- cout << endl;
-
- for (auto e : s)
- {
- cout << e << " ";
- }
- cout << endl;
- }
- }
RBTree.h
- pragma once
-
- enum Colour
- {
- RED,
- BLACK,
- };
-
- template<class T>
- struct RBTreeNode
- {
- RBTreeNode
* _left; - RBTreeNode
* _right; - RBTreeNode
* _parent; - T _data; // 数据
-
- Colour _col;
-
- RBTreeNode(const T& data)
- :_data(data)
- , _left(nullptr)
- , _right(nullptr)
- , _parent(nullptr)
- , _col(RED)
- {}
- };
-
- template<class T, class Ref, class Ptr>
- struct __RBTreeIterator
- {
- typedef RBTreeNode
Node; - typedef __RBTreeIterator
Self; - Node* _node;
-
- __RBTreeIterator(Node* node)
- :_node(node)
- {}
-
- Ref operator*()
- {
- return _node->_data;
- }
-
- Ptr operator->()
- {
- return &_node->_data;
- }
- // 休息17:00
- Self& operator++() //中序遍历
- {
- if (_node->_right == nullptr) //当前节点的右节点为空
- {
- // 就找祖先里面,孩子是父亲左的那个父亲
- Node* cur = _node;
- Node* parent = cur->_parent;
- while (parent && parent->_right == cur)
- { //只要这个父亲的孩子不是父亲的左,就继续往上找
- cur = cur->_parent;
- parent = parent->_parent;
- }
- //直到这个父亲的孩子是父亲的左,这个父亲就是该++走到的节点
- _node = parent;
- }
- else //当前节点的右节点不为空
- {
- // 就走完右子树的最左节点
- Node* subLeft = _node->_right;
- while (subLeft->_left)
- {
- subLeft = subLeft->_left;
- }
-
- _node = subLeft;
- }
-
- return *this;
- }
-
- Self operator++(int)
- {
- Self tmp(*this);
-
- ++(*this);
-
- return tmp;
- }
-
- Self& operator--()
- {
- if (_node->_left == nullptr)
- {
- // 找祖先里面,孩子是父亲
- Node* cur = _node;
- Node* parent = cur->_parent;
- while (parent && cur == parent->_left)
- {
- cur = cur->_parent;
- parent = parent->_parent;
- }
-
- _node = parent;
- }
- else
- {
- // 左子树的最右节点
- Node* subRight = _node->_left;
- while (subRight->_right)
- {
- subRight = subRight->_right;
- }
-
- _node = subRight;
- }
-
- return *this;
- }
-
- Self operator--(int)
- {
- Self tmp(*this);
-
- --(*this);
-
- return tmp;
- }
-
- bool operator!=(const Self& s) const
- {
- return _node != s._node;
- }
-
- bool operator==(const Self& s) const
- {
- return _node == s->_node;
- }
- };
-
- // T决定红黑树存什么数据
- // set RBTree
- // map RBTree
> - // KeyOfT -> 支持取出T对象中key的仿函数
- template<class K, class T, class KeyOfT>
- class RBTree
- {
- typedef RBTreeNode
Node; - public:
- typedef __RBTreeIterator
iterator; - typedef __RBTreeIterator
const T&, const T*> const_iterator; -
- // 构造 拷贝构造 赋值 和析构 跟搜索树实现方式是一样的
-
- iterator Begin()
- {
- Node* subLeft = _root;
- while (subLeft && subLeft->_left)
- {
- subLeft = subLeft->_left;
- }
-
- return iterator(subLeft);
- }
-
- iterator End()
- {
- return iterator(nullptr);
- }
-
- const_iterator Begin() const
- {
- Node* subLeft = _root;
- while (subLeft && subLeft->_left)
- {
- subLeft = subLeft->_left;
- }
-
- return const_iterator(subLeft);
- }
-
- const_iterator End() const
- {
- return const_iterator(nullptr);
- }
-
- pair
bool > Insert(const T& data) - {
- // 1、搜索树的规则插入
- // 2、看是否违反平衡规则,如果违反就需要处理:旋转
- if (_root == nullptr)
- {
- _root = new Node(data);
- _root->_col = BLACK;
- return make_pair(iterator(_root), true);
- }
-
- KeyOfT kot;
-
- Node* parent = nullptr;
- Node* cur = _root;
- while (cur)
- {
- if (kot(cur->_data) < kot(data))
- {
- parent = cur;
- cur = cur->_right;
- }
- else if (kot(cur->_data) > kot(data))
- {
- parent = cur;
- cur = cur->_left;
- }
- else
- {
- return make_pair(iterator(cur), true);
- }
- }
-
- cur = new Node(data);
- Node* newnode = cur;
- cur->_col = RED;
- if (kot(parent->_data) < kot(data))
- {
- parent->_right = cur;
- }
- else
- {
- parent->_left = cur;
- }
-
- cur->_parent = parent;
-
- // 存在连续红色节点
- while (parent && parent->_col == RED)
- {
- Node* grandfater = parent->_parent;
- assert(grandfater);
-
- if (grandfater->_left == parent)
- {
- Node* uncle = grandfater->_right;
- // 情况一:
- if (uncle && uncle->_col == RED) // 叔叔存在且为红
- {
- // 变色
- parent->_col = uncle->_col = BLACK;
- grandfater->_col = RED;
-
- // 继续往上处理
- cur = grandfater;
- parent = cur->_parent;
- }
- else // 叔叔不存在 或者 叔叔存在且为黑
- {
- if (cur == parent->_left) // 单旋
- {
- // g
- // p
- // c
- RotateR(grandfater);
- parent->_col = BLACK;
- grandfater->_col = RED;
- }
- else // 双旋
- {
- // g
- // p
- // c
- RotateL(parent);
- RotateR(grandfater);
- cur->_col = BLACK;
- grandfater->_col = RED;
- }
-
- break;
- }
- }
- else //(grandfater->_right == parent)
- {
- Node* uncle = grandfater->_left;
- // 情况一:
- if (uncle && uncle->_col == RED)
- {
- // 变色
- parent->_col = uncle->_col = BLACK;
- grandfater->_col = RED;
-
- // 继续往上处理
- cur = grandfater;
- parent = cur->_parent;
- }
- else
- {
- if (cur == parent->_right)
- {
- // g
- // p
- // c
- RotateL(grandfater);
- parent->_col = BLACK;
- grandfater->_col = RED;
- }
- else // 双旋
- {
- // g
- // p
- // c
- RotateR(parent);
- RotateL(grandfater);
- cur->_col = BLACK;
- grandfater->_col = RED;
- }
-
- break;
- }
- }
- }
-
- _root->_col = BLACK;
-
- return make_pair(iterator(newnode), true);
- }
-
- void RotateL(Node* parent)
- {
- Node* subR = parent->_right;
- Node* subRL = subR->_left;
-
- parent->_right = subRL;
- if (subRL)
- subRL->_parent = parent;
-
- Node* ppNode = parent->_parent;
-
- subR->_left = parent;
- parent->_parent = subR;
-
- if (parent == _root)
- {
- _root = subR;
- _root->_parent = nullptr;
- }
- else
- {
- if (parent == ppNode->_left)
- {
- ppNode->_left = subR;
- }
- else
- {
- ppNode->_right = subR;
- }
-
- subR->_parent = ppNode;
- }
- }
-
- void RotateR(Node* parent)
- {
- Node* subL = parent->_left;
- Node* subLR = subL->_right;
-
- parent->_left = subLR;
- if (subLR)
- subLR->_parent = parent;
-
- Node* ppNode = parent->_parent;
-
- subL->_right = parent;
- parent->_parent = subL;
-
- if (parent == _root)
- {
- _root = subL;
- _root->_parent = nullptr;
- }
- else
- {
- if (ppNode->_left == parent)
- {
- ppNode->_left = subL;
- }
- else
- {
- ppNode->_right = subL;
- }
- subL->_parent = ppNode;
- }
- }
-
- iterator Find(const K& key)
- {
- Node* cur = _root;
- KeyOfT kot;
- while (cur)
- {
- if (kot(cur->_data) < key)
- {
- cur = cur->_right;
- }
- else if (kot(cur->_data) > key)
- {
- cur = cur->_left;
- }
- else
- {
- return iterator(cur);
- }
- }
-
- return End();
- }
-
- private:
- Node* _root = nullptr;
- };
-
相关阅读:
python3读取yaml文件
[ jquery 选择器 :nth-of-type() ] 选取指定类型(p)父元素下的第几个子元素
扬帆起航:CCF开源发展论坛在深举办
Idea部署dubbo-admin
深入解读GLIDE/PITI代码
零数科技荣获2022金融科技创新引领奖
大数据Doris(二):Doris原理篇
[思维]Yet Another Problem Codeforces1747D
MMLAB系列:MMCLS基本操作
企业安全—SDL概述篇
-
原文地址:https://blog.csdn.net/zhang_si_hang/article/details/126398107