map和set


自己对自己有定位,如果链表都没掌握,就不要来看这里的

Node* it//原生指针,解引用 :节点
list<int> : :iterator it//自定义类型 解引用 :里面的数据
set<int> : : iterator it
//都是4个字节,都存了1个节点的地址;类型赋予空间意义

set

源码

template <class Key, class Compare, class Alloc = alloc>
#endif
class set {
public:
// typedefs:
typedef Key key_type ;
typedef Key value_type ; 
typedef Compare key_compare;
typedef Compare value_compare);
private :
typedef rb_tree<key type, value type ,
identity<value_type>, key_compare,Alloc>
rep type ;
rep type t; // red-black tree representing set

应用

#include<iostream>
#include <set>
#include <map>
#include <string>
using namespace std;

void test_set()
{set<int> s1;
	s1.insert(3);
	s1.insert(2);
	set<int>::iterator it1 = s1.begin();
	while (it1 != s1.end())//方法1
	{	cout << *it1 << " ";
		++it1;
	}
	cout << endl;
	for (auto e : s1)//方法2
	{
		cout << e << " ";
	}
	cout << endl;
	string strs[] = { "sort", "sort", "insert", "sort", "map" };
	set<string> strunique;
	for (auto& str : strs)
	{
		strunique.insert(str);
	}
	for (auto& str : strunique)
	{
		cout << str << " ";
	}
	cout << endl;
	//方法1: 时间复杂度=O(N),使用算法里的find
	auto ret = std::find(strunique.begin(), strunique.end(), "sort");
	if (ret != strunique.end())
	{
		cout << "找到了" << endl;
	}
	//方法2: 时间复杂度=O(logN),使用set里的find
	ret = strunique.find("sort");
	if (ret != strunique.end())
	{
		cout << "找到了" << endl;
	}
}
int main()
{	test_set();
	//test_map();
	return 0;
}

MySet.h

封装红黑树:逻辑不复杂,结构复杂

#pragma once
#include "RBTree.h"

namespace bit
{
	template<class K>
	class set
	{
		struct SetKOfT
		{//重载operator()
			const K& operator()(const K& k)
			{
				return k;
			}
		};
	public:
		typedef typename RBTree<K, K, SetKOfT>::Iterator iterator;//对类型重命名为iterator,编译器找不到RBTree<K, K, SetKOfT>类模板,类模板在实例化时生成其代码,所以使用前置声明typename,实例化之后找不到Iterator再报错,
		//迭代器:非递归;有3叉链parent,不需要栈;
		iterator begin()
		{
			return _t.Begin();
		}

		iterator end()
		{
			return _t.End();
		}

		pair<RBTreeNode<K>*, bool> insert(const K& k)
		{
			return _t.Insert(k);
		}

	private:
		RBTree<K, K, SetKOfT> _t;//有2个k原因:和map复用同1个树
	};

	void test_set()
	{
		set<int> s;
		s.insert(1);
		s.insert(20);
		s.insert(12);
		s.insert(2);
		s.insert(23);
		s.insert(21);
		s.insert(2);
		s.insert(30);

		set<int>::iterator it = s.begin();
		while (it != s.end())
		{
			cout << *it << " ";
			++it;
		}
		cout<<endl;
	}
}

map

源码

template <class Key,class T, class Compareclass Alloc = alloc>
class map {
public:
typedef Key key_type ;
typedef T data_type ;
typedef T mapped_type ;
typedef pair<const Key, T> value _type ;
typedef Compare key_compare;
private:
typedef rb_tree<key _type, value type ,
selectlst<value type>, key compare,Alloc>
rep type ;
rep _type t; // red-black tree representing map
public:
} ;

若是统计次数,则T是sting int,value _type是sting int的pair,

应用

void test_map()
{
	map<string, string> dict;
	dict.insert(pair<string, string>("字符串", "string"));
	dict.insert(pair<string, string>("排序", "sort"));
	map<string, string>::iterator dit = dict.begin();
	while (dit != dict.end())
	{
cout << (*dit).first << ":" << (*dit).second << endl;//方法1
cout << dit->first << ":" << dit->second << endl;//方法2
		++dit;
	}
	for (auto& e : dict)
	{
		cout << e.first << ":" << e.second << endl;//方法3
	}
	string strs[] = { "sort", "sort", "insert", "sort", "map" };
	map<string, int> countMap;//统计次数
	/*方法1:	for (auto& s : strs)
	{
		auto ret = countMap.find(s);
		if (ret != countMap.end())
		{
			ret->second++;
		}
		else
		{//如果没找到,就插入进去
countMap.insert(pair<string, int>(s, 1));//方法1,声明模板参数类型
countMap.insert(make_pair(s, 1));//方法2,不需要写类型,通过实参推演出形参,然后返回构造出的对象
		}
	}*/
	for (auto& s : strs)//方法2
	{
		countMap[s]++;
	}
	for (auto& e : countMap)
	{
		cout << e.first << ":" << e.second << endl;
	}
}

结果:排序:sort
字符串:string
排序:sort
字符串:string
insert : 1
map:1
sort : 3

template<class K, class V>//函数模板
inline pair<K,V>make_pair(const K& k,const V& v){
return pair<K,V>(k,v);}
//调用返回不会有效率损失,因为是inline

MyMap.h

#pragma once
#include "RBTree.h"

namespace bit
{
	template<class K, class V>
	class map
	{
		struct MapKOfT
		{
			const K& operator()(const pair<const K, V>& kv)
			{
				return kv.first;
			}
		};

	public:
		pair<RBTreeNode<pair<const K, V>>*, bool> insert(const pair<const K, V>& kv)
		{
			return _t.Insert(kv);
		}

	private:
		RBTree<K, pair<const K, V>, MapKOfT> _t;
	};

	void test_map()
	{
		map<int, int> m;
		m.insert(make_pair(1, 1));
		m.insert(make_pair(2, 1));
		m.insert(make_pair(3, 1));

	}
}

最喜欢的k种水果


void GetFavoriteFruit(const vector<string>& fruits, size_t k)
{
	typedef map<string, int>::iterator CountMapIt;
	map<string, int> countMap;//统计每种水果的次数,比较int,map.
	for (auto& e : fruits)
	{
		countMap[e]++;
	}
// 排序 1、vecctor+sort 
//2、multimap 水果作value,k作次数,
//multiset 只能存1个值:结构体pair
	vector<CountMapIt> v;//迭代器从大小的角度说就是节点的指针,迭代器=封装过的指针,节点的指针=地址=4个字节.vector里放CountMapIt迭代器
	CountMapIt it = countMap.begin();//不能使用范围for,取不到CountMapIt的迭代器
	while (it != countMap.end())
	{
		v.push_back(it);
		++it;
	}
//sort(v.begin(),v.end()),这样写时过不了的,需要加一个仿函数,对vector的迭代器解引用之后是map的迭代器,迭代器支持比较比较大小,second是次数,first是水果
	struct CountMapItCompare//仿函数
	{
		bool operator()(const CountMapIt& it1,
			const CountMapIt& it2)
		{//使用大于号> :降序;优先级队列:建大堆时使用小于号;
			return it1->second > it2->second;
		}
	};
	sort(v.begin(), v.end(), CountMapItCompare());//传匿名对象;把5种水果按次数排序;sort底层是快排;函数参数传对象 CountMapItCompare()
	for (auto& e : v)//把前K种取出来
	{
		cout << e->first << ":" << e->second << endl;//迭代器使用->
		k--;
		if (k == 0)
		{
			break;
		}
	}
}
int main()
{
	vector<string> v = { "西瓜", "西瓜", "西瓜", "西瓜", "香蕉", "香蕉", "香蕉", "榴莲", "榴莲", "榴莲", "榴莲", "榴莲", "榴莲", "苹果", "苹果", "苹果", "苹果", "苹果" };
	GetFavoriteFruit(v, 3);//榴莲:6苹果:5西瓜:4
	return 0;
}

692. 前K个高频单词

输入: [“i”, “love”, “leetcode”, “i”, “love”, “coding”], k = 2
输出: [“i”, “love”]
“i” 和 “love” 为出现次数最多的两个单词,均为2次。按字母顺序 “i” 在 “love” 之前

class Solution {
public:
	vector<string> topKFrequent(vector<string>& words, int k) 
	{
		typedef map<string, int> ::iterator CountMapIt;
		// count 3insert 4string 2words 3
		//string count words insert
		map<string, int> countMap;//map悄悄的已经以string的ascii值排序,从小到大的放,为了排序的稳定性,不使用sort排(底层是快排)
		for (auto& e : words)
		{//统计words的次数
			countMap[e]++;
		}
		multimap<int, string, greater<int>> sortMap;//仿函数里使用的greater,模板参数传类型greater<int>,函数参数传对象
		for (auto& e : countMap)
		{//second:次数:K,first:字符串
			sortMap.insert(make_pair(e.second, e.first));
		}
		vector<string> v;
		auto rit = sortMap.begin();
		 while (k--)
		{
			v.push_back(rit->second);
			++rit;
		}
		return v;
	}
};

AVL树

#pragma once

template<class K, class V>
struct AVLTreeNode
{
	AVLTreeNode<K, V>* _left;
	AVLTreeNode<K, V>* _right;
	AVLTreeNode<K, V>* _parent; // 不是必须
	pair<K, V> _kv;
	int _bf;  // 平衡因子=左右高度差  不是必须

	AVLTreeNode(const pair<K, V>& kv)//调构造函数的地方:创建节点
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _kv(kv)
		, _bf(0)//刚创建的节点的平衡因子都是0
	{}
};

template<class K, class V>
struct AVLTree
{
	typedef AVLTreeNode<K, V> Node;
public:
	AVLTree() = default;//default关键字,强制编译器自己生成
	AVLTree(const AVLTree<K, V>& t);//拷贝构造
	AVLTree<K, V>& operator=(AVLTree<K, V> t);//现代写法
	~AVLTree();

	pair<Node*, bool> Insert(const pair<K, V>& kv)
	{
		if (_root == nullptr)
		{
			_root = new Node(kv);
			return make_pair(_root, true);// k:_root, v:true
		}
//树已经产生,开始插入
		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)//cur走到空时插入进去
		{//_kv是pair,first比完之后 second比
			if (cur->_kv.first < kv.first)
			{//kv大,则往右树去走
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_kv.first > kv.first)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{//已经存在,则不能插入,返回节点指针;如果要返回迭代器,用节点的指针可以构建1个迭代器
				return make_pair(cur, false);
			}
		}

		cur = new Node(kv);
		if (parent->_kv.first < kv.first)
		{//插到parent的右边
			parent->_right = cur;
			cur->_parent = parent;//3叉链,要链起来
		}
		else
		{
			parent->_left = cur;
			cur->_parent = parent;
		}
//以上代码把搜索树已经完成
		Node* newnode = cur;//保存cur,cur一直在变化
		// 1、更新平衡因子;新增节点会影响它到根节点这条路径上的祖先
		while (parent)
		{
			if (cur == parent->_right)
			{
				parent->_bf++;
			}
			else
			{
				parent->_bf--;
			}

			if (parent->_bf == 0)
			{
				break;
			}
			else if (abs(parent->_bf) == 1)
			{
				cur = parent;
				parent = parent->_parent;
			}
			else if (abs(parent->_bf) == 2)
			{
				// 旋转
				if (parent->_bf == -2)
				{
					if (cur->_bf == -1)
					{
						RotateR(parent);
					}
					else // cur->_bf == 1
					{
						RotateLR(parent);
					}
				}
				else //parent->_bf == 2
				{
					if (cur->_bf == 1)
					{
						RotateL(parent);
					}
					else // cur->_bf == -1
					{
						RotateRL(parent);
					}
				}

				break;
			}
			else
			{
				assert(false);
			}
		}

		return make_pair(newnode, true);
	}

	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

		parent->_left = subLR;
		if (subLR)
			subLR->_parent = parent;
//下面要修改parentParent的左、右,这里先保存起来
		Node* parentParent = parent->_parent;

		subL->_right = parent;
		parent->_parent = subL;

		if (parent == _root)
		{
			_root = subL;
			_root->_parent = nullptr;//根的父亲是空
		}
		else
		{//图2中的60可能不是根,60的上面还有节点
			if (parentParent->_left == parent)
			{
				parentParent->_left = subL;
			}
			else
			{
				parentParent->right = subL;
			}

			subL->_parent = parentParent;
		}

		subL->_bf = parent->_bf = 0;
	}

	void RotateL(Node* parent)
	{//和类隔离开时,为了可以修改_root,有时改为void RotateL(Node* parent,Node*& root)
Node* subR = parent->_right;
		Node* subRL = subR->_left;

		parent->_right = subRL;
		if (subRL)
		{
			subRL->_parent = parent;
		}

		subR->_left = parent;

		Node* parentParent = parent->_parent;
		parent->_parent = subR;

		if (_root == parent)//不是成员函数则访问不到_root
		{
			_root = subR;
		}
		else
		{
			if (parentParent->_left == parent)
			{
				parentParent->_left = subR;
			}
			else
			{
				parentParent->_right = subR;
			}
		}

		subR->_parent = parentParent;//B指向A,A也要指向B

		parent->_bf = subR->_bf = 0;
	}
	void RotateLR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = parent->_left->_parent;
		int bf = subLR->_bf;//平衡因子会变化,先保存起来

		RotateL(parent->_left);
		RotateR(parent);

		if (bf == 1)  // 说明subLR是右树插入
		{
			subLR->_bf = 0;
			parent->_bf = 0;
			subL->_bf = -1;
		}
		else if (bf == -1)  // 说明subLR是左树插入
		{
			subLR->_bf = 0;
			subL->_bf = 0;
			parent->_bf = 1;

		}
		else // bf == 0 // 说明subLR是新增节点
		{
			subL->_bf = subLR->_bf = parent->_bf = 0;
		}

	}

	void RotateRL(Node* parent)
	{
Node* subR = parent->_right;
		Node* subRL = subR->_left;
		int bf = subRL->_bf;

		RotateR(parent->_right);
		RotateL(parent);

		if (bf == 0)
		{
			subRL->_bf = subR->_bf = parent->_bf = 0;
		}
		else if (bf == 1)
		{
			subR->_bf = 0;
			parent->_bf = -1;
			subRL->_bf = 0;
		}
		else if (bf == -1)
		{
			subR->_bf = 1;
			parent->_bf = 0;
			subRL->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}
int Height(Node* root)模板是按需实例化,
	{
		if (root == NULL)
		{
			return 0;
		}

		return max(Height(root->_left), Height(root->_right)) + 1;
	}
	bool _IsBalance(Node* root)
	{
		if (root == NULL)
		{
			return true;
		}

		int leftHeight = Height(root->_left);//调用Height
		int rightHeight = Height(root->_right);

		if (rightHeight-leftHeight != root->_bf)
		{
			cout << "平衡因子异常:"<<root->_kv.first<<endl;
		}


		return abs(leftHeight - rightHeight) < 2
			&& _IsBalance(root->_left)
			&& _IsBalance(root->_right);
	}
void _InOrder(Node* root)//和void InOrder()构成函数重载
	{
		if (root == NULL)
			return;

		_InOrder(root->_left);
		cout << root->_kv.first << " ";
		_InOrder(root->_right);
	}

	void InOrder()//无法传参所以无法递归
	{
		_InOrder(_root);
		cout<<endl;
	}
		bool IsBalance()///检查是否是平衡树
	{
		_IsBalance(_root);
	}

	Node* Find(const K& key);
	V& operator[](const K& key);
	bool Erase(const K& key);
private:
	Node* _root = nullptr;
};
int main()
{
	int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
	AVLTree<int, int> t;

	for (auto e : a)
	{
		t.Insert(make_pair(e, e));
	}

	t.InOrder();

	cout<<t.IsBalance()<<endl;
	return 0;
}

红黑树

红黑树比AVL树少旋转次数
情况一: cur为红,p为红,g为黑,u存在且为红:在这里插入图片描述
2条路径各增加1个黑结点,父亲改为红,使得每条路径的黑色结点数量在改变前后不变。不旋转则不关注p在g的左还是右)

情况二: cur为红,p为红,g为黑,u不存在:
在这里插入图片描述
情况二: cur为红,p为红,g为黑,u为黑
在这里插入图片描述

旋转:降高度、均衡左右2边
情况三: cur为红,p为红,g为黑,u不存在
在这里插入图片描述
情况三: cur为红,p为红,g为黑,u为黑
在这里插入图片描述
红黑树的删除:
添加链接描述
添加链接描述

#pragma once

enum Colour
{
	RED,
	BLACK
};


template<class K, class V>
struct RBTreeNode
{
	RBTreeNode<K, V>* _left;
	RBTreeNode<K, V>* _right;
	RBTreeNode<K, V>* _parent;
	pair<K, V> _kv;

	enum Colour _col;

	RBTreeNode(const pair<K, V>& kv)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _kv(kv)
		, _col(RED)
	{}
};

template<class K, class V>
struct RBTree
{
	typedef RBTreeNode<K, V> Node;
public:
	// ...

	pair<Node*, bool> Insert(const pair<K, V>& kv)
	{
		if (_root == nullptr)
		{
			_root = new Node(kv);

			_root->_col = BLACK;
			return make_pair(_root, true);
		}

		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (cur->_kv.first < kv.first)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_kv.first > kv.first)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return make_pair(cur, false);
			}
		}

		cur = new Node(kv); // RED
		if (parent->_kv.first < kv.first)
		{
			parent->_right = cur;
			cur->_parent = parent;
		}
		else
		{
			parent->_left = cur;
			cur->_parent = parent;
		}

		Node* newnode = cur;
		
		// 
		while (parent && parent->_col == RED)
		{
			Node* grandfather = parent->_parent;
			if (grandfather->_left == parent)
			{
				Node* uncle = grandfather->_right;
				// 情况1:u存在且为红
				if (uncle && uncle->_col == RED)
				{
					// 变色
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;

					// 继续往上处理
					cur = grandfather;
					parent = cur->_parent;
				}
				else //  情况2+3:u不存在或存在且为黑
				{
					//        g
					//      p
					//   c
					//
					if (cur == parent->_left)  // 
					{
						RotateR(grandfather);
						parent->_col = BLACK;
						grandfather->_col = RED;
					}
					else
					{
						//        g
						//      p
						//         c
						//
						RotateL(parent);
						RotateR(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}

					break;
				}
			}
			else // grandfather->_right == parent
			{
				Node* uncle = grandfather->_left;
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;

					cur = grandfather;
					parent = cur->_parent;
				}
				else //  情况2+3:u不存在或存在且为黑
				{
					if (cur == parent->_right)
					{
						RotateL(grandfather);
						grandfather->_col = RED;
						parent->_col = BLACK;
					}
					else
					{
						RotateR(parent);
						RotateL(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}

					break;
				}
			}
		}


		_root->_col = BLACK;
		return make_pair(newnode, true);
	}


	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

		parent->_left = subLR;
		if (subLR)
			subLR->_parent = parent;

		Node* parentParent = parent->_parent;

		subL->_right = parent;
		parent->_parent = subL;

		if (parent == _root)
		{
			_root = subL;
			_root->_parent = nullptr;
		}
		else
		{
			if (parentParent->_left == parent)
			{
				parentParent->_left = subL;
			}
			else
			{
				parentParent->_right = subL;
			}

			subL->_parent = parentParent;
		};
	}

	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;

		parent->_right = subRL;
		if (subRL)
		{
			subRL->_parent = parent;
		}

		subR->_left = parent;

		Node* parentParent = parent->_parent;
		parent->_parent = subR;

		if (_root == parent)
		{
			_root = subR;
		}
		else
		{
			if (parentParent->_left == parent)
			{
				parentParent->_left = subR;
			}
			else
			{
				parentParent->_right = subR;
			}
		}

		subR->_parent = parentParent;
	}

	void _InOrder(Node* root)
	{
		if (root == NULL)
			return;

		_InOrder(root->_left);
		cout << root->_kv.first << " ";
		_InOrder(root->_right);
	}

	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}

	bool _CheckRedCol(Node* root)
	{
		if (root == nullptr)
		{
			return true;
		}

		if (root->_col == RED)
		{
			Node* parent = root->_parent;
			if (parent->_col == RED)
			{
				cout << "违反规则2:存在连续的红色节点" << endl;
				return false;
			}
		}

		return _CheckRedCol(root->_left) && _CheckRedCol(root->_right);
	}
//根结点到此结点时黑色结点的数量,
//传值:你++,不会影响我;引用:你++,影响我
//每个递归建立栈帧,计算所有路径上的黑色节点个数
	bool _CheckBlackNum(Node* root, int blackNum, int trueNum)
	{
		if (root == nullptr)
		{
			// 当走到NULL时, blackNum 这条路径黑色节点的数量
			return trueNum == blackNum;
		}

		if (root->_col == BLACK)
		{
			blackNum++;
		}

		return  _CheckBlackNum(root->_left, blackNum, trueNum)
			&& _CheckBlackNum(root->_right, blackNum, trueNum);
	}

	bool IsBalance()
	{
		if (_root && _root->_col == RED)
		{
			cout << "违反规则1:根节点是红色的"<<endl;
			return false;
		}

		int trueNum = 0;
		Node* cur = _root;
		while (cur)
		{
			if (cur->_col == BLACK)
			{
				++trueNum;
			}
			cur = cur->_left;//1路往坐走下去
		}

		int blackNum = 0;
		return _CheckRedCol(_root)
			&& _CheckBlackNum(_root, blackNum, trueNum);
	}

private:
	Node* _root = nullptr;
};

void TestRBTree()
{
	//int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15};
	int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14, 16, 3, 7, 11, 9, 26, 18, 14, 15};
	RBTree<int, int> t;

	for (auto e : a)
	{
		if (e == 18)//已经知道在18处出错,检查此处时,使用if,条件断点,满足此条件时停下来
		{
			int i = 0;
		}

		t.Insert(make_pair(e, e));
		cout << e << ":";
		cout << t.IsBalance() << endl;
	}

	t.InOrder();

	cout << t.IsBalance() << endl;
}

stl_tree.h(源码):

struct  rb_tree_ node_ basd: {//基类,用继承关系分2层,目的:隔离,节点分为父子,
typedef rb tree_color_type color_type ;
typedef rb tree node base* base ptr;
template <class Value>
//基类里存的节点的结构,没有存节点的值,基类不存数据,node的子类存数据,
struct _ rb tree node:public _ rb_tree _node base
{
typedef_rb ree_ndde value>* link_type ;
Value valu_field;//数据类型
};
set<K> 里是rb_tree<K,K> t
map<K,V>里是 rb_tree<K,pair<const K,V>> t

template <class Key,class value,class KeyOfValue>
class rb tree {//Value不是map<K,V>中的value,他代表的意义是:红黑树中存的值的类型,决定树里存什么,set里存k(=value=_t), map里存pair(=value=_t),模板参数
//KeyOfValue:仿函数:取出Value(t)中的key


protected:
typedef __rb_tree_node_base* base ptr;
typedef _rb_tree_node<Value> rb_tree_node ;
public:
typedef Key key _type ;
typedef value value_type ;
typedef rb_tree_node* link_type ;
protected:
size_type node_count; // keeps track of size of tree
link type header;//类似哨兵位

在这里插入图片描述
最左节点=中序的第1个,

RBTree.h

更高维度的泛型,可能是set 也可能是map在使用这个红黑树,红黑树自身是不知道T的类型;pair自身也可以用value比大小,但我们现在需要的是只拿k比;

#pragma once

enum Colour
{
	RED,
	BLACK
};

template<class T>
struct RBTreeNode
{
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;
	T _t;

	enum Colour _col;

	RBTreeNode(const T& t)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _t(t)
		, _col(RED)
	{}
};

template<class T, class Ref, class Ptr>
struct RBTreeIterator
{
	typedef RBTreeIterator<T, Ref, Ptr> Self;
	typedef RBTreeNode<T> Node;
	Node* _node;
	RBTreeIterator(Node* node)
		:_node(node)
	{}

	Ref operator*()//解引用里面数据
	{
		return _node->_t;
	}
//对于set来说,*it可以直接的取到Key值
	//但是对于map来说,it->first
	Ptr operator->()
	{
		return &(_node->_t);//如果是map那么这里返回的是一个pair<const K,V>*
	}

	// ++it,前置++,即中序的下一个,左子树 根 右子树,可以不掌握迭代器
	Self& operator++()
	{
		if (_node->_right)
		{
			// 右树的最左节点
			Node* cur = _node->_right;
			while (cur && cur->_left)
			{
				cur = cur->_left;
			}

			_node = cur;
		}
		else
		{
			// 右为空,_node所在的子树已经访问完了,
			// 沿着路径往跟走,找孩子不是父亲的右的那个祖先
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && parent->_right == cur)
			{
				cur = parent;
				parent = parent->_parent;
			}

			_node = parent;
		}

		return *this;
	}
//--it
Self& operator--()
{//中序的下一个,左不为空,左树的最后节点
	if(_node->_left)
	{
		//左树的最右节点
		Node* cur = _node->_left; 
		while (cur && cur->_right)
		{
			cur = cur->_right;
		}
		_node = cur;
	}
	else{
		//左为空,_node所在的子树已经访问完了,
		// 沿着路径往跟走.找孩子丕是父亲的左的那全祖先
		Node* cur = _node;
		Node* parent = cur->_parent;
		while (parent && parent->_left == cur)
		{
			cur = parent;
			parent = parent->_parent;
		}
		_node = parent;
	}
		return*this;
}
	bool operator!=(const Self s) const
	{//比较迭代器也是比较节点指针
		return _node != s._node;
	}
};


// set<K>    改造后-> RBTree<K, K>
// map<K, V> 改造后-> RBTree<K,pair<const K, V>>
template<class K, class T, class KeyOfT>
struct RBTree
{
public:
	typedef RBTreeIterator<T, T&, T*> Iterator;
	//const迭代器:
	typedef RBTreeIterator<T, const T&, const T*> ConstIterator;

	Iterator Begin()
	{//用节点Node迭代器
		Node* cur = _root;
		while (cur && cur->_left)
		{//找到最左节点
			cur = cur->_left;
		}

		return Iterator(cur);//匿名对象
	}

	Iterator End()//最后1个节点的 下一个
	{
		return Iterator(nullptr);
	}

	typedef RBTreeNode<T> Node;
	
	//bool Find(const K& k);
	pair<Node*, bool> Insert(const T& t)//节点指针Node*
	{
		KeyOfT kot;

		if (_root == nullptr)
		{
			_root = new Node(t);

			_root->_col = BLACK;
			return make_pair(_root, true);
		}

		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{//不能是if (cur_t < t),当t是pair时这样比较大小时会出错
			if (kot(cur->_t) < kot(t))//调用operator(),返回k
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (kot(cur->_t) > kot(t))
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return make_pair(cur, false);
			}
		}

		cur = new Node(t); // RED
		if (kot(parent->_t) < kot(t))
		{
			parent->_right = cur;
			cur->_parent = parent;
		}
		else
		{
			parent->_left = cur;
			cur->_parent = parent;
		}

		Node* newnode = cur;
		
		// 
		while (parent && parent->_col == RED)
		{
			Node* grandfather = parent->_parent;
			if (grandfather->_left == parent)
			{
				Node* uncle = grandfather->_right;
				// 情况1:u存在且为红
				if (uncle && uncle->_col == RED)
				{
					// 变色
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;

					// 继续往上处理
					cur = grandfather;
					parent = cur->_parent;
				}
				else //  情况2+3:u不存在或存在且为黑
				{
					//        g
					//      p
					//   c
					//
					if (cur == parent->_left)  // 
					{
						RotateR(grandfather);
						parent->_col = BLACK;
						grandfather->_col = RED;
					}
					else //双旋
					{
						//        g
						//      p
						//         c
						//
						RotateL(parent);
						RotateR(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}

					break;
				}
			}
			else // grandfather->_right == parent
			{
				Node* uncle = grandfather->_left;
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;

					cur = grandfather;
					parent = cur->_parent;
				}
				else //  情况2+3:u不存在或存在且为黑
				{
					if (cur == parent->_right)
					{
						RotateL(grandfather);
						grandfather->_col = RED;
						parent->_col = BLACK;
					}
					else
					{
						RotateR(parent);
						RotateL(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}

					break;
				}
			}
		}


		_root->_col = BLACK;
		return make_pair(newnode, true);
	}


	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

		parent->_left = subLR;
		if (subLR)
			subLR->_parent = parent;

		Node* parentParent = parent->_parent;

		subL->_right = parent;
		parent->_parent = subL;

		if (parent == _root)
		{
			_root = subL;
			_root->_parent = nullptr;
		}
		else
		{
			if (parentParent->_left == parent)
			{
				parentParent->_left = subL;
			}
			else
			{
				parentParent->_right = subL;
			}

			subL->_parent = parentParent;
		};
	}

	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;

		parent->_right = subRL;
		if (subRL)
		{
			subRL->_parent = parent;
		}

		subR->_left = parent;

		Node* parentParent = parent->_parent;
		parent->_parent = subR;

		if (_root == parent)
		{
			_root = subR;
		}
		else
		{
			if (parentParent->_left == parent)
			{
				parentParent->_left = subR;
			}
			else
			{
				parentParent->_right = subR;
			}
		}

		subR->_parent = parentParent;
	}

private:
	Node* _root = nullptr;
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值