赞
踩
目录
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<set>
(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<int>::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>
原因: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<const key_type,mapped_type>)
pair中的first就相当于KV模型中的key,second相当于KV模型中的val
make_pair 相当于返回了一个pair的匿名对象
几种插入英汉字典的方式:匿名对象插入,普通对象插入,make_pair插入
- void test_map1()
- {
- map<string, string> dict;
-
- // pair构造函数
- dict.insert(pair<string, string>("sort", "排序")); //匿名对象插入更便捷
- pair<string, string> kv("insert", "插入"); //普通对象插入
- dict.insert(kv);
-
- // make_pair
- auto ret1 = dict.insert(make_pair("left", "左边")); //make_pair插入
- auto ret2 = dict.insert(make_pair("left", "剩余"));
- // 遍历
- //map<string, string>::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<string, int> countMap;
- for (auto& str : arr)
- {
- map<string, 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<string, int> countMap;
- for (auto& str : arr)
- {
- pair<map<string, int>::iterator, bool> ret = countMap.insert(make_pair(str, 1));
- //或者 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<map<string, int>::iterator, bool> ret = countMap.insert(make_pair(str, 1)) 插入节点,若插入成功,ret.first这个iterator 存的是新插入节点的迭代器,ret.second 存的是true;若插入失败,ret.first这个iterator 存的是已有的相同节点的迭代器,ret.second 存的是false;插入失败就再记录个数++就行,ret.first->second++; 用于访问记录水果个数,ret.first 是节点迭代器,ret.first->second++; 节点中的second用于记录对应水果的个数
- void test_map2()
- {
- string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
- map<string, 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<string, string> dict;
-
- // pair构造函数
- dict.insert(pair<string, string>("sort", "排序"));
- pair<string, string> 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<string,int>::iterator CountIter;
- struct less
- {
- bool operator()(const pair<string,int>& x,const pair<string,int>& y)
- {
- return x.second>y.second;
- }
- };
-
- vector<string> topKFrequent(vector<string>& words, int k) {
- map<string,int> countMap;
- for(auto& str:words)
- {
- countMap[str]++;
- }
-
- vector<pair<string,int>> v;
- CountIter it=countMap.begin();
- while(it!=countMap.end())
- {
- //cout<<it->first<<" "<<it->second<<endl;
- v.push_back(*it);
- ++it;
- }
-
- stable_sort(v.begin(),v.end(),less()); //stable_sort稳定排序
- vector<string> vv;
- for(int i=0;i<k;i++)
- {
- vv.push_back(v[i].first);
- }
- for(auto e:v)
- {
- cout<<e.first<<" "<<e.second<<endl;
- }
- return vv;
- }
- };
与做法一不同的是:pair很大,为了减少拷贝,我们可以选择不拷贝pair而是拷贝迭代器,把map中的迭代器放到v中,比较方法中通过迭代器找到second,再用stable_sort稳定排序这些迭代器,再把各个迭代器对应的first放到vv中,再输出vv
自己敲的:
- class Solution {
- public:
- typedef map<string,int>::iterator CountIter;
- struct less //降序
- {
- bool operator()(const CountIter& x,const CountIter& y)
- {
- return x->second > y->second;
- }
- };
-
- vector<string> topKFrequent(vector<string>& words, int k) {
- map<string,int> countMap;
- for(auto& str:words)
- {
- countMap[str]++;
- }
-
- vector<CountIter> v;
- CountIter it=countMap.begin();
- while(it!=countMap.end())
- {
- //cout<<it->first<<" "<<it->second<<endl;
- v.push_back(it);
- ++it;
- }
-
- stable_sort(v.begin(),v.end(),less()); //stable_sort稳定排序
- for(auto e:v)
- {
- cout<<e->first<<" "<<e->second<<endl;
- }
- vector<string> vv;
- for(int i=0;i<k;i++)
- {
- vv.push_back(v[i]->first);
- }
-
- return vv;
- }
- };
相比较上面的方法,把stable_sort换成sort后,只需要控制比较方法即可使其稳定:因为map中默认是按照分first小的在前排序的,sort 时我们设计的比较方法是按second排序的,但是当second相等时,sort有可能打乱之前map中按 first 排的先后顺序,这样就是不稳定。我们只需要比较方法中让second相等时的情况再按first小的在前排好就可以达到稳定的目的。(相等时会多比一下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<int>。
- class Solution {
- public:
- vector<string> topKFrequent(vector<string>& words, int k) {
- map<string,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<<it->first<<" "<<it->second<<endl;
- // ++it;
- // }
- vector<string> vv;
- auto it=sortMap.begin();
- for(int i=0;i<k;i++)
- {
- vv.push_back(it->second);
- ++it;
- }
-
- return vv;
- }
- };
官方写法:
重点:
struct SetKeyOfT 仿函数,用于在RBTree.h找到map/set中所要比较的值,用于控制RBTree.h中pair类型的比较方法,因为库中的pair类型 先比first再比second 的比较方法不是我们想要的
- #pragma once
- #include "RBTree.h"
-
- namespace bit
- {
- template<class K, class V>
- class map
- {
- struct MapKeyOfT
- {
- const K& operator()(const pair<K, V>& kv)
- {
- return kv.first;
- }
- };
- public:
- typedef typename RBTree<K, pair<K, V>, MapKeyOfT>::iterator iterator;
- typedef typename RBTree<K, pair<K, V>, MapKeyOfT>::const_iterator const_iterator;
-
- iterator begin()
- {
- return _t.Begin();
- }
-
- iterator end()
- {
- return _t.End();
- }
-
- pair<iterator, bool> insert(const pair<K, V>& kv)
- {
- return _t.Insert(kv);
- }
-
- iterator find(const K& key)
- {
- return _t.Find(key);
- }
-
- V& operator[](const K& key)
- {
- pair<iterator, bool> ret = insert(make_pair(key, V()));
- return ret.first->second;
- }
-
- private:
- RBTree<K, pair<K, V>, MapKeyOfT> _t;
- };
-
- void test_map1()
- {
- map<string, 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<string, 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<string, int> countMap;
- for (auto& str : arr)
- {
- countMap[str]++;
- }
-
- for (const auto& kv : countMap)
- {
- cout << kv.first << ":" << kv.second << endl;
- }
- }
-
- void test_map3()
- {
- map<string, string> dict;
- dict["insert"];
- dict["insert"] = "";
- dict["left"] = "";
-
- }
- }
- #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<K, K, SetKeyOfT>::const_iterator iterator;
- typedef typename RBTree<K, K, SetKeyOfT>::const_iterator const_iterator;
-
- iterator begin() const //set内容不想被修改(key值不修改),则给this设置const,
- { //调用时会调用带const的Begin()
- return _t.Begin();
- }
-
- iterator end() const
- {
- return _t.End();
- }
-
- pair<iterator, bool> insert(const K& key)
- {
- //pair<typename RBTree<K, K, SetKeyOfT>::iterator, bool> ret = _t.Insert(key);
- auto ret = _t.Insert(key);
- return pair<iterator, bool>(iterator(ret.first._node), ret.second);
- }
-
- iterator find(const K& key)
- {
- return _t.Find(key);
- }
- private:
- RBTree<K, K, SetKeyOfT> _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;
- }
- }
- pragma once
-
- enum Colour
- {
- RED,
- BLACK,
- };
-
- template<class T>
- struct RBTreeNode
- {
- RBTreeNode<T>* _left;
- RBTreeNode<T>* _right;
- RBTreeNode<T>* _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<T> Node;
- typedef __RBTreeIterator<T, Ref, Ptr> 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<K, K>
- // map RBTree<K, pair<K, V>>
- // KeyOfT -> 支持取出T对象中key的仿函数
- template<class K, class T, class KeyOfT>
- class RBTree
- {
- typedef RBTreeNode<T> Node;
- public:
- typedef __RBTreeIterator<T, T&, T*> iterator;
- typedef __RBTreeIterator<T, 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<iterator, 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;
- };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。