文章目录
前言:
- 想了解map与set就得先知道其是由 平衡搜索二叉树 为底层实现的一种数据结构,与二叉搜索树不同的是其就有自我调节高度能力(当然是需要我们写代码维护其性质)
- 常见的平衡二叉树有两种 AVLTree , 红黑树(RBTree)
- 为什么不用 二叉搜索树 呢?因为其如果插入的数据为有序时会成为单链表的形态,查找数据时,时间复杂度退化成 O(N)
- 平衡二叉搜索树 对每一次的插入数据就会进行判断是否需要调节,每棵树具体的调节方式下文讲解
Ⅰ. AVLTree
前言:
- AVLTree 是由两位俄罗斯的数学家 G.M.Adelson-Velskii 和 E.M.Landis 在1962年提出的,为解决二叉搜索树的退化成链表问题而孕育而生的
- AVLTree 是保证左右子树的高度差在 -1 <= 右高度 - 左高度 <= 1 的范围内,这样就可以降低树的高度,从而降低树的平均查找长度
- 根据定义,插入若 插入其右其 右- 左 的高度差 + + ,插入其左 右 - 左 的高度差 - - ,若不在规定的范围就需要调整,就是所谓的旋转,将子或父旋转到祖父的位置
- 考虑一下插入的情况一共有几种? 先分大方向,要么插入到根的 左子树或者右子树,其两棵树高度如果相等,随便插入无需理会
- 若插入 较高左子树 可插入左边右边
- 若插入 较高右子树 可插入左边右边
// 节点声明
template<class K,class V>
struct TreeNode
{
TreeNode<K,V>* _left;
TreeNode<K,V>* _right;
TreeNode<K,V>* _parent;
pair<K, V> _kv;
int _bf;
TreeNode(const pair<K,V> kv)
:_left(nullptr),_right(nullptr),_parent(nullptr),_kv(kv),_bf(0)
{}
};
1. 插入右旋
较高左子树的左插入
首先解释一下为什么这一幅图片就可以代表 左旋的 所有情况:
- 若a b 高度不同,对于30 来说 是不是又会被细分为 大方向上的 四种情况? 即左右子树较高的左右侧插入
- 若无30节点,那60的左右子树高度相等 即意味着 随便插入也不会导致平衡高度因子变为超出范围,故无需旋转
- 若a b c 树的高度不同
a. a b 小于c一层 加上30后高度与c相等,重回2情况
b. a b 大于c一层60的平衡因子超出范围,为-2 ,故等不到新节点的插入,其就不平衡了,就意味着插入之前就得调节平衡了
接下来的操作就是将b作为60的左,而60作为30的右,这样就可以使其左右高度差为0
为什么可以这样旋转呢?
因为由二叉搜索树的性质 a < 30 < b < 60 < c
我让b作为60的左,c作为60的右不过分吧 ? 接着我让这棵新形成的树作为30 的右,a作为30的左也不过分吧?
这样旋转完成后,仍满足二叉搜索树的性质,这就是点睛之笔
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;
subL->_parent = nullptr;
}
else
{
if (parent == ppnode->_left)
{
ppnode->_left = subL;
}
else
{
ppnode->_right = subL;
}
subL->_parent = ppnode;
}
parent->_bf = subL->_bf = 0;
}
2. 插入左旋
较高右子树的右插入
插入左旋同理可得:
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;
subR->_parent = nullptr;
}
else
{
if (parent == ppnode->_left)
{
ppnode->_left = subR;
}
else
{
ppnode->_right = subR;
}
subR->_parent = ppnode;
}
parent->_bf = subR->_bf = 0;
}
3. 插入左右双旋
插入较高左子树的右侧
可能右三种情况:
就是60本身(即h==0);
60的左边 (即h > 0)
60的右边 (即h > 0 )
为什么此时需要分三种情况? 因为单旋需要两次单旋,单旋30时会导致不同的子树进行重新组合,平衡因子的调节会有所不同
遇到不平衡,继续使用单旋,但是旋转过后发现仍然不平衡,所以这时候就不得不想其他方法了,单旋不行的原因大概就是,这棵树的左子树并不是单纯的一边高,这就好比child想上位,将parent压下来,但是给parent的手下太多了,child管不住,本身单旋是child的手下很多,给parent的手下很少,可以制约平衡,这时候就想将child给parent的手下先拿走一点,然后再进行单旋就行了,即对child的左单旋,然后再对parent右单旋
void RotateLR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
int bf = subLR->_bf;
RotateL(subL);
RotateR(parent);
if (bf == 0)
{
parent->_bf = 0;
subL->_bf = 0;
subLR->_bf = 0;
}
else if (bf == 1)
{
parent->_bf = 0;
subL->_bf = -1;
subLR->_bf = 0;
}
else if (bf == -1)
{
parent->_bf = 1;
subL->_bf = 0;
subLR->_bf = 0;
}
}
4. 插入右左双旋
在较高右子树的左侧插入
也分三种情况,自己,左子树内,右子树内
同理可得:
void RotateRL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
int bf = subRL->_bf;
RotateR(subR);
RotateL(parent);
if (bf == 0)
{
parent->_bf = 0;
subR->_bf = 0;
subRL->_bf = 0;
}
else if (bf == -1)
{
parent->_bf = 0;
subR->_bf = 1;
subRL->_bf = 0;
}
else if (bf == 1)
{
subRL->_bf = 0;
parent->_bf = -1;
subR->_bf = 0;
}
}
5. 底层实现
底层的实现
template<class K,class V>
struct TreeNode
{
TreeNode<K,V>* _left;
TreeNode<K,V>* _right;
TreeNode<K,V>* _parent;
pair<K, V> _kv;
int _bf;
TreeNode(const pair<K,V> kv)
:_left(nullptr),_right(nullptr),_parent(nullptr),_kv(kv),_bf(0)
{}
};
template<class K,class V>
class AVLTree
{
typedef TreeNode<K, V> Node;
public:
bool insert(const pair<K, V>& kv)
{
if (_root == nullptr)
{
_root = new Node(kv);
return true;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (kv.first < cur->_kv.first)
{
parent = cur;
cur = cur->_left;
}
else if(kv.first > cur->_kv.first)
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
cur = new Node(kv);
if (kv.first < parent->_kv.first) parent->_left = cur;
else parent->_right = cur;
cur->_parent = parent;
while (parent)
{
if (cur == parent->_left) parent->_bf--;
else parent->_bf++;
if (parent->_bf == 0)
{
break;
}
else if (parent->_bf == 1 || parent->_bf == -1)
{
cur = parent;
parent = cur->_parent;
}
else if (parent->_bf == 2 || parent->_bf == -2)
{
if (parent->_bf == 2 && cur->_bf == 1)
{
RotateL(parent);
}
else if (parent->_bf == -2 && cur->_bf == -1)
{
RotateR(parent);
}
else if (parent->_bf == 2 && cur->_bf == -1)
{
RotateRL(parent);
}
else if (parent->_bf == -2 && cur->_bf == 1)
{
RotateLR(parent);
}
else
{
assert(false);
}
break;
}
else
{
assert(false);
}
}
return true;
}
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;
subL->_parent = nullptr;
}
else
{
if (parent == ppnode->_left)
{
ppnode->_left = subL;
}
else
{
ppnode->_right = subL;
}
subL->_parent = ppnode;
}
parent->_bf = subL->_bf = 0;
}
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;
subR->_parent = nullptr;
}
else
{
if (parent == ppnode->_left)
{
ppnode->_left = subR;
}
else
{
ppnode->_right = subR;
}
subR->_parent = ppnode;
}
parent->_bf = subR->_bf = 0;
}
void RotateLR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
int bf = subLR->_bf;
RotateL(subL);
RotateR(parent);
if (bf == 0)
{
parent->_bf = 0;
subL->_bf = 0;
subLR->_bf = 0;
}
else if (bf == 1)
{
parent->_bf = 0;
subL->_bf = -1;
subLR->_bf = 0;
}
else if (bf == -1)
{
parent->_bf = 1;
subL->_bf = 0;
subLR->_bf = 0;
}
}
void RotateRL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
int bf = subRL->_bf;
RotateR(subR);
RotateL(parent);
if (bf == 0)
{
parent->_bf = 0;
subR->_bf = 0;
subRL->_bf = 0;
}
else if (bf == -1)
{
parent->_bf = 0;
subR->_bf = 1;
subRL->_bf = 0;
}
else if (bf == 1)
{
subRL->_bf = 0;
parent->_bf = -1;
subR->_bf = 0;
}
}
void inorder()
{
_inorder(_root);
}
bool isbalance()
{
return _isbalance(_root);
}
int height()
{
return _height(_root);
}
int size()
{
return _size(_root);
}
private:
int _size(Node* root)
{
return root == nullptr ? 0 : _size(root->_left) + _size(root->_right) + 1;
}
void _inorder(Node* root)
{
if (root == nullptr) return;
_inorder(root->_left);
cout << root->_kv.first << "->" << root->_kv.second << endl;
_inorder(root->_right);
}
int _height(Node* root)
{
if (root == nullptr) return 0;
int left = _height(root->_left);
int right = _height(root->_right);
return max(left, right) + 1;
}
bool _isbalance(Node* root)
{
if (root == nullptr) return true;
int left = _height(root->_left);
int right = _height(root->_right);
if (abs(left - right) >= 2) return false;
if (right - left != root->_bf) return false;
return _isbalance(root->_left)
&& _isbalance(root->_right);
}
private:
Node* _root = nullptr;
};
Ⅱ. RBTree
前言:
- 有AVLTree为什么还要有红黑树呢?因为AVLTree的要求太过苛刻,要求左右高度差不超过1,这就意味着插入的时候需要频繁旋转调整
- 有人提出了红黑树(即相对不严格的平衡二叉树),即最长路径不超过最短路径二倍的树
- 因为在logN的查找时间复杂度中,多加几层的查找无关紧要,结果仍然是查找的很快
- 红黑树的要求:1. 根节点必须是黑色,2. 且不能存在连续的红色节点,3.每条路径上具有相同的黑色点个数,4.若此节点为红色,那么它的两个孩子必须为黑色
- 为什么红黑树的这几点性质,就能保证其最长路径不超过最短路径二倍?因为最短无疑是全黑,最长无疑是在黑节点之间插入红(一黑一红,或两黑无红),其红不能连续,且红后必为黑,也有可能相邻黑之间无红,这就可以保证所有路径中最长路径不超过最短路径的二倍
// 节点定义
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;
colour _col;
RBTreeNode(const pair<K,V> & kv)
:_left(nullptr),_right(nullptr),_parent(nullptr),_kv(kv),_col(RED)
{}
};
因为插入节点默认为红色,如果为黑色,就改变了所有路径黑色节点个数一样的性质,此性质难以把握,故插入红色,而插入红色时,若父亲为黑,无需理会直接插入,若插入节点的父亲是红色,则不满足无连续红节点的性质,所以需要向上调整颜色
1. 插入后只变色
父亲的兄弟为红时
将parent变黑,grandfather变红,迭代向上变
2. 插入后旋转加变色
父亲无兄弟,或有兄弟且为黑时
仅仅将parent变黑已经 不满足所有路径黑色节点数量一致的性质,但此时如果将grandfather进行有单旋外加变色就可以保持平衡
3. 底层实现
template<class K, class V>
class RBTree
{
typedef RBTreeNode<K, V> Node;
public:
bool Insert(const pair<K, V>& kv)
{
if (_root == nullptr)
{
_root = new Node(kv);
_root->_col = BLACK;
return true;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (kv.first < cur->_kv.first)
{
parent = cur;
cur = cur->_left;
}
else if (kv.first > cur->_kv.first)
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
cur = new Node(kv);
if (kv.first < parent->_kv.first)
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 = uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else
{
if (cur == parent->_left)
{
RotateR(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
RotateL(parent);
RotateR(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
else
{
Node* uncle = grandfather->_left;
if (uncle && uncle->_col == RED)
{
parent->_col = uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else
{
if (cur == parent->_right)
{
RotateL(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
RotateR(parent);
RotateL(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
}
_root->_col = BLACK;
return true;
}
void RotateR(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 (parent == _root)
{
_root = subL;
_root->_parent = nullptr;
}
else
{
if (ppNode->_left == parent)
{
ppNode->_left = subL;
}
else
{
ppNode->_right = subL;
}
subL->_parent = ppNode;
}
}
void RotateL(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 (parent == _root)
{
_root = subR;
_root->_parent = nullptr;
}
else
{
if (ppNode->_right == parent)
{
ppNode->_right = subR;
}
else
{
ppNode->_left = subR;
}
subR->_parent = ppNode;
}
}
void Inorder()
{
_Inorder(_root);
cout << endl;
}
bool IsBalance()
{
// 规则一
if (_root->_col != BLACK)
{
return false;
}
int blacksum = 0;
Node* cur = _root;
while (cur)
{
if (cur->_col == BLACK) blacksum++;
cur = cur->_left;
}
return check(_root, 0, blacksum);
}
private:
bool check(Node* root, int path, int blacksum)
{
if (root == nullptr)
{
// 规则四
if (path != blacksum)
{
return false;
}
return true;
}
// 规则三
if (root->_col == RED && root->_parent->_col == RED)
return false;
if (root->_col == BLACK) path++;
return check(root->_left, path, blacksum)
&& check(root->_right, path, blacksum);
}
void _Inorder(Node* root)
{
if (root == nullptr) return;
_Inorder(root->_left);
cout << root->_kv.first << " " << root->_kv.second << endl;
_Inorder(root->_right);
}
private:
Node* _root = nullptr;
};
Ⅲ. map set的封装
1. map
template<class K,class V>
class map
{
struct MapKeyofT
{
const K& operator()(const pair<const K,V>& kv)
{
return kv.first;
}
};
public:
typedef typename RBTree<K, pair<const K, V>, MapKeyofT>::Iterator iterator;
typedef typename RBTree<K, pair<const K, V>, MapKeyofT>::Const_Iterator const_iterator;
iterator begin()
{
return _t.Begin();
}
iterator end()
{
return _t.End();
}
const_iterator begin() const
{
return _t.Begin();
}
const_iterator end() const
{
return _t.End();
}
pair<iterator,bool> insert(const pair<const K, V>& kv)
{
return _t.Insert(kv);
}
iterator find(const K& k)
{
return _t.Find(k);
}
V& operator[](const K& k)
{
pair<iterator, bool> ret = _t.Insert(make_pair(k, V()));
return ret.first->second;
}
private:
RBTree<K, pair<const K, V> ,MapKeyofT> _t;
};
2. set
template<class K>
class set
{
struct SetKeyofT
{
const K& operator()(const K& k)
{
return k;
}
};
public:
typedef typename RBTree<K,const K, SetKeyofT>::Iterator iterator;
typedef typename RBTree<K,const K, SetKeyofT>::Const_Iterator const_iterator;
iterator begin()
{
return _t.Begin();
}
iterator end()
{
return _t.End();
}
const_iterator begin() const
{
return _t.Begin();
}
const_iterator end() const
{
return _t.End();
}
pair<iterator, bool> insert(const K& k)
{
return _t.Insert(k);
}
iterator find(const K& k)
{
return _t.Find(k);
}
private:
RBTree<K,const K, SetKeyofT> _t;
};
3.完善RBTree
#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)
:_left(nullptr),_right(nullptr),_parent(nullptr),_data(data),_col(RED)
{}
};
template<class T,class Ref,class Ptr>
struct __RBTree_Iterator
{
typedef RBTreeNode<T> Node;
typedef __RBTree_Iterator<T, Ref, Ptr> Self;
Node* _node;
__RBTree_Iterator(Node* node)
:_node(node)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &_node->_data;
}
bool operator!=(const Self& s)
{
return _node != s._node;
}
Self& operator++()
{
if (_node->_right)
{
Node* leftMin = _node->_right;
while (leftMin->_left)
leftMin = leftMin->_left;
_node = leftMin;
}
else
{
Node* cur = _node;
Node* parent = cur->_parent;
while (parent && cur == parent->_right)
{
cur = parent;
parent = cur->_parent;
}
_node = parent;
}
return *this;
}
};
template<class K, class T,class KeyOfT>
class RBTree
{
typedef RBTreeNode<T> Node;
public:
typedef __RBTree_Iterator<T, T&, T*> Iterator;
typedef __RBTree_Iterator<T,const T&,const T*> Const_Iterator;
Iterator Begin()
{
Node* leftMin = _root;
while (leftMin && leftMin->_left)
leftMin = leftMin->_left;
return Iterator(leftMin);
}
Iterator End()
{
return Iterator(nullptr);
}
Const_Iterator Begin() const
{
Node* leftMin = _root;
while (leftMin && leftMin->_left)
leftMin = leftMin->_left;
return Iterator(leftMin);
}
Const_Iterator End() const
{
return Iterator(nullptr);
}
RBTree() = default;
RBTree(const RBTree<K, T, KeyOfT>& t)
{
_root = copy(t._root);
}
RBTree<K, T, KeyOfT>& operator=(RBTree<K, T, KeyOfT> t)
{
std::swap(_root, t._root);
return *this;
}
~RBTree()
{
destroy(_root);
_root = nullptr;
}
pair<Iterator,bool> Insert(const T& data)
{
if (_root == nullptr)
{
_root = new Node(data);
_root->_col = BLACK;
return make_pair(Iterator(_root), false);
}
KeyOfT kot;
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (kot(data) < kot(cur->_data))
{
parent = cur;
cur = cur->_left;
}
else if (kot(data) > kot(cur->_data))
{
parent = cur;
cur = cur->_right;
}
else
{
return make_pair(Iterator(cur), true);
}
}
cur = new Node(data);
Node* newnode = cur;
if (kot(data) < kot(parent->_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 = uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else
{
if (cur == parent->_left)
{
RotateR(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
RotateL(parent);
RotateR(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
else
{
Node* uncle = grandfather->_left;
if (uncle && uncle->_col == RED)
{
parent->_col = uncle->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else
{
if (cur == parent->_right)
{
RotateL(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
RotateR(parent);
RotateL(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
}
_root->_col = BLACK;
return make_pair(Iterator(newnode), false);
}
Iterator Find(const K& k)
{
KeyOfT kot;
Node* cur = _root;
while (cur)
{
if (k < kot(cur->_data))
{
cur = cur->_left;
}
else if(k > kot(cur->_data))
{
cur = cur->_right;
}
else
{
return Iterator(cur);
}
}
return Iterator(nullptr);
}
void RotateR(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 (parent == _root)
{
_root = subL;
_root->_parent = nullptr;
}
else
{
if (ppNode->_left == parent)
{
ppNode->_left = subL;
}
else
{
ppNode->_right = subL;
}
subL->_parent = ppNode;
}
}
void RotateL(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 (parent == _root)
{
_root = subR;
_root->_parent = nullptr;
}
else
{
if (ppNode->_right == parent)
{
ppNode->_right = subR;
}
else
{
ppNode->_left = subR;
}
subR->_parent = ppNode;
}
}
bool IsBalance()
{
if (_root == nullptr) return true;
if (_root->_col != BLACK)
return false;
int blacksum = 0;
Node* cur = _root;
while (cur)
{
if (cur->_col == BLACK) blacksum++;
cur = cur->_left;
}
return check(_root, 0, blacksum);
}
private:
bool check(Node* root, int path, int blacksum)
{
if (root == nullptr)
{
if (path != blacksum)
return false;
return true;
}
if (root->_col == RED && root->_parent->_col == RED)
return false;
if (root->_col == BLACK)
path++;
return check(root->_left, path, blacksum)
&& check(root->_right, path, blacksum);
}
void destroy(Node* root)
{
if (root == nullptr)
return;
destroy(root->_left);
destroy(root->_right);
delete root;
root = nullptr;
}
Node* copy(Node* root)
{
if (root == nullptr)
return nullptr;
Node* newnode = new Node(root->_data);
newnode->_col = root->_col;
newnode->_left = copy(root->_left);
if (newnode->_left)
newnode->_left->_parent = newnode;
newnode->_right = copy(root->right);
if (newnode->_right)
newnode->_right->_parent = newnode;
return newnode;
}
private:
Node* _root = nullptr;
};