赞
踩
这是关于一个普通双非本科大一学生的C++的学习记录贴
在此前,我学了一点点C语言还有简单的数据结构,如果有小伙伴想和我一起学习的,可以私信我交流分享学习资料
那么开启正题
今天分享的是关于RBTree模拟实现
RBTree(红黑树),是一种二叉搜索树,在每个结点增加一个存储标识结点颜色,可以是RED或者BLACK(因而得名),通过对任意一条叶子路径上的各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因而使近似平衡的
1.根节点是黑色的
2.没有相邻的红结点
3. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点
4. 每个空结点都是黑色的
RBTree结点是一种三岔链,不仅存储了左右子树结点的指针,还要存储父亲结点的指针,当然还要存储结点颜色以及pair
- enum Colour
- {
- BLACK,
- RED
- };
-
- 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)
- , _col(RED)
- , _kv(kv)
- {}
- };
RBTree树插入数据可以分为两步
1.按照二叉搜索树的方式插入新结点
2.调整结点的颜色
在调节颜色时,有时需要旋转处理,旋转方式和我们刚学的AVLTree旋转方式一样
先按照二叉搜索树进行插入,当然注意颜色的处理
- 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 (cur->_kv.first < kv.first)
- {
- parent = cur;
- cur = cur->_right;
- }
- else if (cur->_kv.first > kv.first)
- {
- parent = cur;
- cur = cur->_left;
- }
- else
- {
- return false;
- }
- }
-
- cur = new Node(kv);
- cur->_col = RED;
- if (parent->_kv.first < kv.first)
- {
- parent->_right = cur;
- cur->_parent = parent;
- }
- else
- {
- parent->_left = cur;
- cur->_parent = parent;
- }
-
-
- //。。。。。
-
- _root->_col = BLACK;
-
- return true;
- }
当叔叔为红色时,把叔叔父亲变为黑,祖父变为红,往上继续迭代即可
当叔叔叔叔为黑色或不存在时,要进行旋转,旋转完成调色后,退出循环
- while (parent && parent->_col == RED)
- {
- Node* grandfater = parent->_parent;
- if (parent == grandfater->_left)
- {
- Node* uncle = grandfater->_right;
- // 情况一 uncle存在且为红
- if (uncle && uncle->_col == RED)
- {
- parent->_col = uncle->_col = BLACK;
- grandfater->_col = RED;
-
- cur = grandfater;
- parent = cur->_parent;
- }
- else
- {
- if (cur == parent->_left)
- {
- // 情况二
- RotateR(grandfater);
- parent->_col = BLACK;
- grandfater->_col = RED;
- }
- else
- {
- // 情况三
- RotateL(parent);
- RotateR(grandfater);
- cur->_col = BLACK;
- grandfater->_col = RED;
- }
-
- break;
- }
- }
- else // (parent == grandfater->_right)
- {
- Node* uncle = grandfater->_left;
- if (uncle && uncle->_col == RED)
- {
- parent->_col = uncle->_col = BLACK;
- grandfater->_col = RED;
-
- cur = grandfater;
- parent = cur->_parent;
- }
- else
- {
- // g
- // p
- // c
- if (cur == parent->_right)
- {
- RotateL(grandfater);
- parent->_col = BLACK;
- grandfater->_col = RED;
- }
- else
- {
- // g
- // p
- // c
- RotateR(parent);
- RotateL(grandfater);
- cur->_col = BLACK;
- grandfater->_col = RED;
- }
-
- break;
- }
- }
- }
注意::完成后,根可能为红色(违反红黑树性质),要处理为黑色
当然红黑树还有其他函数,以及迭代器,这些在后面模拟实现map和set里再深入探究
新手写博客,有不对的位置希望大佬们能够指出,也谢谢大家能看到这里,让我们一起学习进步吧!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。