1.红黑树源码
我们使用上节课的红黑树源码来封装map和set.
因为map存的是(key,value),set存的是(key),为了我们set和map使用同一个类模板(红黑树),所以我们先要修改红黑树结点中存的数据类型,我们使用模板来初始化,根据实列化来决定结点中存的是pair,还是只有一个数据
做出修改:代码中所有key的地方用data代替,而data的数据类型是T,当是set实列化的时候T就是int(一种),当是map的时候T就是pair,比方说pair<string,int>
#include<iostream>
#include<string>
using namespace std;
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)
:_left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _data(data)
, _col(RED)
{}
};
template<class T>
class rbtree
{
typedef rbtreenode<T> node;
public:
void spinleft(node* parent)
{
node* subr = parent->_right;
node* subrl = subr->_left;
parent->_right = subrl;
if (subrl)
subrl->_parent = parent;
subr->_left = parent;
node* ppnode = parent->_parent;
parent->_parent = subr;
if (ppnode == nullptr)
{
_root = subr;
subr->_parent = nullptr;
}
else
{
if (ppnode->_left == parent)
{
ppnode->_left = subr;
subr->_parent = ppnode;
}
else
{
ppnode->_right = subr;
subr->_parent = ppnode;
}
}
}
void spinright(node* parent)
{
node* subl = parent->_left;
node* sublr = subl->_right;
parent->_left = sublr;
if (sublr)
sublr->_parent = parent;
subl->_right = parent;
node* ppnode = parent->_parent;
parent->_parent = subl;
if (ppnode == nullptr)
{
_root = subl;
subl->_parent = nullptr;
}
else
{
if (ppnode->_left == parent)
{
ppnode->_left = subl;
subl->_parent = ppnode;
}
else
{
ppnode->_right = subl;
subl->_parent = ppnode;
}
}
}
void spinlr(node* parent)
{
node* subl = parent->_left;
node* sublr = subl->_right;
//int bf = sublr->_bf;
spinleft(parent->_left);
spinright(parent);
/* if (bf == 1)
{
subl->_bf = -1;
sublr->_bf = 0;
parent->_bf = 0;
}
else if (bf == -1)
{
subl->_bf = 0;
sublr->_bf = 0;
parent->_bf = 1;
}
else
{
subl->_bf = 0;
sublr->_bf = 0;
parent->_bf = 0;
}*/
}
void spinrl(node* parent)
{
node* subr = parent->_right;
node* subrl = subr->_left;
//int bf = subrl->_bf;
spinright(subr);
spinleft(parent);
/* if (bf == 1)
{
parent->_bf = -1;
subr->_bf = 0;
subrl->_bf = 0;
}
else if (bf == -1)
{
parent->_bf = 0;
subr->_bf = 1;
subrl->_bf = 0;
}
else
{
subr->_bf = 0;
subrl->_bf = 0;
parent->_bf = 0;
}*/
}
bool insert(const T& data)
{
if (_root == nullptr)
{
_root = new node(data);
_root->_col = BLACK;
return true;
}
node* cur = _root;
node* parent = nullptr;
while (cur)
{
if (cur->_data > data)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_data < data)
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
cur = new node(data);
if (parent->_data > data)
{
parent->_left = cur;
}
else
{
parent->_right = cur;
}
cur->_parent = parent;
while (parent && parent->_col == RED)
{
node* grandfather = parent->_parent;
if (parent == grandfather->_left)
{
node* uncle = grandfather->_right;
if (uncle && uncle->_col == RED)
{
parent->_col = BLACK;
uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else
{
if (cur == parent->_right)
{
spinright(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
spinleft(parent);
spinright(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
else
{
node* uncle = grandfather->_left;
if (uncle && uncle->_col == RED)
{
parent->_col = BLACK;
uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else
{
if (cur == parent->_left)
{
spinleft(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
spinright(parent);
spinleft(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
}
_root->_col = BLACK;
return true;
}
bool Check(node* cur)
{
if (cur == nullptr)
return true;
if (cur->_col == RED && cur->_parent->_col == RED)
{
cout << cur->_key<< "存在连续的红色节点" << endl;
return false;
}
return Check(cur->_left)
&& Check(cur->_right);
}
bool IsBalance()
{
if (_root && _root->_col == RED)
return false;
return Check(_root);
}
void inorder()
{
_inorder(_root);
}
void _inorder(node* root)
{
if (root == nullptr)
return;
_inorder(root->_left);
cout << root->_data << endl;
_inorder(root->_right);
}
node* Find(const T& data)
{
node* cur = _root;
node* parent = nullptr;
while (cur)
{
if (cur->_data > data)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_data < _data)
{
parent = cur;
cur = cur->_right;
}
else
{
return cur;
}
}
return nullptr;
}
private:
int treeheight(node* root)
{
if (root == nullptr)
return 0;
int leftheight = treeheight(root->_left);
int rightheight = treeheight(root->_right);
return leftheight > rightheight ? leftheight + 1 : rightheight + 1;
}
node* _root = nullptr;
};
int main()
{
rbtree<int>st;
int a[] = //{ 16,3,1 };//测试右旋
//{ 16,32,58 };//测试左旋
//{ 8,3,1,10,6,4};//测试右左旋
{ 4, 2, 6, 1, 3, 5, 15, 7, 16,14 };
for (auto e : a)
{
st.insert(e);
}
st.inorder();
int ret = st.IsBalance();
cout << endl;
cout << ret;
}
2.set和map类的简单封装
#pragma once
#include"rbtree.h"
namespace zjw
{
template<class K,class V>
class map {
public:
private:
rbtree<K,pair<K,V>>_st;
};
}
#pragma once
#include"rbtree.h"
namespace zjw
{
template<class K>
class set {
public:
private:
rbtree<K, K>_st;
};
}
3.map和set调用底层rbtree的insert函数
#pragma once
#include"rbtree.h"
namespace zjw
{
template<class K,class V>
class map {
public:
bool insert(cosnt pair<K, V>& kv)
{
return _st.insrt(kv);
}
private:
rbtree<K,pair<K,V>>_st;
};
}
#pragma once
#include"rbtree.h"
namespace zjw
{
template<class K>
class set {
public:
bool insert(const K& key)
{
return _st.insert(key);
}
private:
rbtree<K, K>_st;
};
}
4.阶段测试
5._data的元素提取
因为我们不管是map还是set,他们插入都是根据第一个模板参数比较大小,来确定插入当前结点的左还是右,但是为什么之前的代码没有报错??
因为如果是map的话,pair也是可以比较大小的,规则是第一个大的大。第一个一样大,就比较第二个,第二个谁大就大
但是我们回顾之前的map和set都是按照第一个比较,所以我们可以这样做。在map和set类中定义内部类,如果rbtree中有需要比较data大小时,初始化一个内部类取data第一个内容来比较,我们只需要在map和set中初始化一个内部类对象即可返回data的第一个内容。
在rbtree中需要比较_data的地方都需要使用类对象来返回data的第一个内容
#pragma once
#include<iostream>
#include<string>
using namespace std;
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)
:_left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _data(data)
, _col(RED)
{}
};
template<class K,class T,class OFKEY>
class rbtree
{
typedef rbtreenode<T> node;
public:
void spinleft(node* parent)
{
node* subr = parent->_right;
node* subrl = subr->_left;
parent->_right = subrl;
if (subrl)
subrl->_parent = parent;
subr->_left = parent;
node* ppnode = parent->_parent;
parent->_parent = subr;
if (ppnode == nullptr)
{
_root = subr;
subr->_parent = nullptr;
}
else
{
if (ppnode->_left == parent)
{
ppnode->_left = subr;
subr->_parent = ppnode;
}
else
{
ppnode->_right = subr;
subr->_parent = ppnode;
}
}
}
void spinright(node* parent)
{
node* subl = parent->_left;
node* sublr = subl->_right;
parent->_left = sublr;
if (sublr)
sublr->_parent = parent;
subl->_right = parent;
node* ppnode = parent->_parent;
parent->_parent = subl;
if (ppnode == nullptr)
{
_root = subl;
subl->_parent = nullptr;
}
else
{
if (ppnode->_left == parent)
{
ppnode->_left = subl;
subl->_parent = ppnode;
}
else
{
ppnode->_right = subl;
subl->_parent = ppnode;
}
}
}
void spinlr(node* parent)
{
node* subl = parent->_left;
node* sublr = subl->_right;
//int bf = sublr->_bf;
spinleft(parent->_left);
spinright(parent);
/* if (bf == 1)
{
subl->_bf = -1;
sublr->_bf = 0;
parent->_bf = 0;
}
else if (bf == -1)
{
subl->_bf = 0;
sublr->_bf = 0;
parent->_bf = 1;
}
else
{
subl->_bf = 0;
sublr->_bf = 0;
parent->_bf = 0;
}*/
}
void spinrl(node* parent)
{
node* subr = parent->_right;
node* subrl = subr->_left;
//int bf = subrl->_bf;
spinright(subr);
spinleft(parent);
/* if (bf == 1)
{
parent->_bf = -1;
subr->_bf = 0;
subrl->_bf = 0;
}
else if (bf == -1)
{
parent->_bf = 0;
subr->_bf = 1;
subrl->_bf = 0;
}
else
{
subr->_bf = 0;
subrl->_bf = 0;
parent->_bf = 0;
}*/
}
bool insert(const T& data)
{
OFKEY sk;
if (_root == nullptr)
{
_root = new node(data);
_root->_col = BLACK;
return true;
}
node* cur = _root;
node* parent = nullptr;
while (cur)
{
if (sk(cur->_data) > sk(data))
{
parent = cur;
cur = cur->_left;
}
else if (sk(cur->_data) < sk(data))
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
cur = new node(data);
if (sk(parent->_data) > sk(data))
{
parent->_left = cur;
}
else
{
parent->_right = cur;
}
cur->_parent = parent;
while (parent && parent->_col == RED)
{
node* grandfather = parent->_parent;
if (parent == grandfather->_left)
{
node* uncle = grandfather->_right;
if (uncle && uncle->_col == RED)
{
parent->_col = BLACK;
uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else
{
if (cur == parent->_right)
{
spinright(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
spinleft(parent);
spinright(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
else
{
node* uncle = grandfather->_left;
if (uncle && uncle->_col == RED)
{
parent->_col = BLACK;
uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else
{
if (cur == parent->_left)
{
spinleft(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
spinright(parent);
spinleft(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
}
_root->_col = BLACK;
return true;
}
bool Check(node* cur)
{
if (cur == nullptr)
return true;
if (cur->_col == RED && cur->_parent->_col == RED)
{
cout << cur->_data << "存在连续的红色节点" << endl;
return false;
}
return Check(cur->_left)
&& Check(cur->_right);
}
bool IsBalance()
{
if (_root && _root->_col == RED)
return false;
return Check(_root);
}
void inorder()
{
_inorder(_root);
}
void _inorder(node* root)
{
if (root == nullptr)
return;
_inorder(root->_left);
cout << root->_data << endl;
_inorder(root->_right);
}
node* Find(const T& data)
{
OFKEY sk;
node* cur = _root;
node* parent = nullptr;
while (cur)
{
if (sk(cur->_data) > sk(data))
{
parent = cur;
cur = cur->_left;
}
else if (sk(cur->_data) < sk(data))
{
parent = cur;
cur = cur->_right;
}
else
{
return cur;
}
}
return nullptr;
}
private:
int treeheight(node* root)
{
if (root == nullptr)
return 0;
int leftheight = treeheight(root->_left);
int rightheight = treeheight(root->_right);
return leftheight > rightheight ? leftheight + 1 : rightheight + 1;
}
node* _root = nullptr;
};
6.迭代器
template<class T,class Pef,class Ptr>
struct _rbtreeIterator
{
typedef rbtreenode<T> node;
typedef _rbtreeIterator<T, Pef, Ptr> Self;
Node* _node;
public:
_rbtreeIterator(Node* node)
:_node(node)
{
//默认构造
}
Self& operator++()
{
//迭代器++
}
Self& operator--()
{
//迭代器--
}
bool operator!=(Self& s)
{
//两个结点是否是同一结点
}
Pef operator*()
{
//重载*
}
Ptr operator->()
{
//重载->
}
};
上面迭代器封装在list里面有说过
template<class T,class Pef,class Ptr>
struct _rbtreeIterator
{
typedef rbtreenode<T> node;
typedef _rbtreeIterator<T, Pef, Ptr> Self;
Node* _node;
public:
_rbtreeIterator(Node* node)
:_node(node)
{
//默认构造
}
Self& operator++()
{
//迭代器++
}
Self& operator--()
{
//迭代器--
}
bool operator!=(Self& s)
{
//两个结点是否是同一结点
return _node != s._node;
}
Pef operator*()
{
//重载*
return _node->_data;
}
Ptr operator->()
{
//重载->
return &_node->_data
}
};
重点说一下迭代器++和–,
Self& operator++()
{
//迭代器++
if (_node->_right)
{
Node* next = _node->_right;
while (next->_left)
{
next = next->_left;
}
_node = next;
}
}
如果_node没有右结点的话,迭代器++下一个位置应该是哪里呢?
比方说_node在6的位置
Self& operator++()
{
//迭代器++
if (_node->_right)
{
Node* next = _node->_right;
while (next->_left)
{
next = next->_left;
}
_node = next;
}
else
{
Node* cur = _node;
Node* parent = cur->_parent;
while (parent && cur == parent->_right)//循环找孩子是父亲左的父亲,该父亲是下一个迭代器的结点
{
cur = parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
同理–
Self& operator--()
{
//迭代器--
if (_node->_left)
{
Node* next = _node->_left;
while (next->_right)
{
next = next->_right;
}
_node = next;
}
else
{
Node* cur = _node;
Node* parent = cur->_parent;
while (parent && cur == parent->_left)
{
cur = parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
红黑树调用迭代器
template<class K,class T,class OFKEY>
class rbtree
{
typedef rbtreenode<T> node;
typedef _rbtreeIterator<T, T&, T*> iterator;
public:
iterator begin()
{
//红黑树根结点的最左结点为最小
node* cur = _root->_left;
while (cur)
{
cur = cur->_left;
}
return iterator(cur);
}
iterator end()
{
//空
return iterator(nullptr);
}
7.set迭代器测试
#pragma once
#include"rbtree.h"
namespace zjw
{
template<class K>
class set {
struct SETOFKEY
{
const K& operator()(const K&key)
{
return key;
}
};
public:
typedef typename rbtree<K, K, SETOFKEY>::iterator iterator;
bool insert(const K& key)
{
return _st.insert(key);
}
iterator begin()
{
return _st.begin();
}
iterator end()
{
return _st.end();
}
private:
rbtree<K, K,SETOFKEY>_st;
};
void testset()
{
set<int>s;
int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16,14 };
for (auto e : a)
{
s.insert(e);
}
set<int>::iterator it = s.begin();
while (it != s.end())
{
cout << *it << endl;
++it;
}
}
}
#include<iostream>
#include<string>
#include"mymap.h"
#include"myset.h"
using namespace std;
int main()
{
//zjw::testmap();
zjw::testset();
}
8.map迭代器测试
#pragma once
#include"rbtree.h"
namespace zjw
{
template<class K,class V>
class map {
struct MAPOFKEY
{
const K& operator()(const pair<K,V>&kv)
{
return kv.first;
}
};
public:
typedef typename rbtree<K, pair<K,V>, MAPOFKEY>::iterator iterator;
bool insert(const pair<K, V>& kv)
{
return _st.insert(kv);
}
iterator begin()
{
return _st.begin();
}
iterator end()
{
return _st.end();
}
private:
rbtree<K,pair<K,V>, MAPOFKEY>_st;
};
void testmap()
{
map<string, int>sr;
sr.insert(make_pair("b", 1));
sr.insert(make_pair("think", 1));
sr.insert(make_pair("cool", 1));
map<string, int>::iterator it = sr.begin();
// //auto it = dic.begin();
while (it != sr.end())
{
cout << it->first << ":" << it->second << endl;
++it;
}
cout << endl;
}
}
#include<iostream>
#include<string>
#include"mymap.h"
#include"myset.h"
using namespace std;
int main()
{
zjw::testmap();
//zjw::testset();
}