红黑树是一种较为平衡的搜索树, 当然满足所有搜索树应该具有的特点.
红黑树的几个性质:
1. 节点或红或黑 2. 根是黑的 3. 叶是黑的(叶均为nil, 是所谓的外节点, 而有值的节点均为内节点)
4. 如果一个节点是红的,则它的子女均为黑的 5. 对于任何节点, 从该节点到该节点的子孙叶节点的所有路径上所包含的黑节点数量相同。
从定义可以得到定理:一颗n个内节点的红黑树高度最多2lg(n+1).
一个完全2叉树的高度是lg(n+1), 所以可见红黑树的平衡性是相当不错的。
红黑树和普通的搜索树相比,主要的区别在于,红黑树进行插入删除之后,很可能会导致树破坏了上述5个性质,因而需要作一些调整: 为了做调整,有两个基础操作,分别是针对一个节点进行左旋或者右旋操作, 这两个操作都不会影响树本身的性质。
下面是我自己写的一些code. 都是根据书中思路所写,书中用数组来表示树, 我用节点来表示,有一些差别。 leftRotate, rightRotate. 除去insert和delete之外,红黑树和搜索树的行为均相同, 其中m_null表示空节点,属于黑节点。
template<class Ty>
class TreeNode
{
public:
typedef Ty value_type;
TreeNode() : m_parent(0), m_left(0), m_right(0) {}
TreeNode(const Ty& __x, TreeNode<Ty>* leftChild, TreeNode<Ty>* rightChild, TreeNode<Ty>* parent)
: m_parent(parent), m_left(leftChild), m_right(rightChild), m_value(__x), m_black(false) {}
TreeNode(const Ty& __x) : m_parent(0), m_left(0), m_right(0), m_black(false) {}
bool m_black;
Ty m_value;
TreeNode<Ty>* m_parent;
TreeNode<Ty>* m_left;
TreeNode<Ty>* m_right;
TreeNode<Ty>* left() {
return m_left;
}
TreeNode<Ty>* right() {
return m_right;
}
TreeNode<Ty>* parent() {
return m_parent;
}
Ty& value() {
return m_value;
}
static TreeNode<Ty>* makeNode(const Ty& __x, TreeNode<Ty>* leftChild = 0, TreeNode<Ty>* rightChild = 0, TreeNode<Ty>* parent = 0)
{
return new TreeNode<Ty>(__x, leftChild, rightChild, parent);
}
bool isRed() const {return !m_black;}
bool isBlack() const {return m_black;}
void setRed() {m_black = false;}
void setBlack() {m_black = true;}
};
typedef TreeNode<Ty> node_type;
void leftRotate(node_type* node)
{
assert(node != m_null);
assert(node->right() != m_null);
node_type* parent = node->parent();
node_type* rightNode = node->right();
node_type* rightNode_leftNode = rightNode->left();
node->m_parent = rightNode;
node->m_right = rightNode_leftNode;
rightNode_leftNode->m_parent = node;
rightNode->m_left = node;
if (parent == m_null) // 如果node是根节点
{
m_root = rightNode;
rightNode->m_parent = m_null;
}
else
{
rightNode->m_parent = parent;
if (parent->left() == node)
{
parent->m_left = rightNode;
}
else
{
parent->m_right = rightNode;
}
}
}
void rightRotate(node_type* node)
{
assert(node != m_null);
assert(node->left() != m_null);
node_type* parent = node->parent();
node_type* leftNode = node->left();
node_type* leftNode_rightNode = leftNode->right();
node->m_parent = leftNode;
node->m_left = leftNode_rightNode;
leftNode_rightNode->m_parent = node;
leftNode->m_right = node;
if (parent == m_null) // 如果node是根节点
{
m_root = leftNode;
leftNode->m_parent = m_null;
}
else
{
leftNode->m_parent = parent;
if (parent->left() == node)
{
parent->m_left = leftNode;
}
else
{
parent->m_right = leftNode;
}
}
}
插入和搜索树插入相仿,只是加入了一些影响红黑的校正部分:
void insert(const value_type& __x)
{
node_type* curNode = m_root;
node_type* node = TreeNode<Ty>::makeNode(__x, m_null, m_null, m_null);
if (!m_root)
{
m_root = node;
m_root->setBlack();
return;
}
while(curNode != m_null)
{
if (m_function(node->value(), curNode->value()))
{
if (curNode->left() != m_null)
{
curNode = curNode->left();
}
else
{
curNode->m_left = node;
node->m_parent = curNode;
break;
}
}
else
{
if (curNode->right() != m_null)
{
curNode = curNode->right();
}
else
{
curNode->m_right = node;
node->m_parent = curNode;
break;
}
}
}
node->setRed();
insertFixup(node);
}
void insertFixup(node_type* node)
{
assert(node != m_null);
assert(node->isRed());
node_type* parent;
node_type* parent_brother;
node_type* grandParent;
while(node->parent()->isRed())
{
parent = node->parent();
grandParent = parent->parent();
if (grandParent->left() == parent) // parent是parentparent的左子女
{
parent_brother = grandParent->right();
if (parent_brother->isRed()) // 叔叔的颜色是红
{
parent->setBlack();
grandParent->setRed();
parent_brother->setBlack();
node = grandParent;
}
else // 叔叔的颜色是黑
{
if (parent->right() == node)
{
leftRotate(parent);
node = parent;
}
parent = node->parent();
rightRotate(grandParent);
grandParent->setRed();
node->parent()->setBlack();
}
}
else
{
parent_brother = grandParent->left();
if (parent_brother->isRed()) // 叔叔的颜色是红
{
parent->setBlack();
grandParent->setRed();
parent_brother->setBlack();
node = grandParent;
}
else // 叔叔的颜色是黑
{
if (parent->left() == node)
{
node = parent;
rightRotate(parent);
}
leftRotate(grandParent);
grandParent->setRed();
node->parent()->setBlack();
}
}
}
m_root->setBlack();
}
删除:
void erase(const value_type& __x)
{
node_type* node = find(__x);
if (node == m_null)
{
return;
}
if (node->left() == m_null || node->right() == m_null)
{
}
else
{
node_type* nextNode = next(node);
std::swap(node->m_value, nextNode->m_value);
node = nextNode;
}
node_type** parent;
if (node->parent() == m_null)
{
parent = &m_root;
}
else
{
if (node->parent()->left() == node)
{
parent = &(node->m_parent->m_left);
}
else
{
parent = &(node->m_parent->m_right);
}
}
node_type* fixPara;
if (node->left() != m_null)
{
fixPara = node->left();
*parent = node->left();
node->m_left->m_parent = node->parent(); // ? node->parent() : m_null;
}
else
{
fixPara = node->right();
*parent = node->right();
// if (node->right() != m_null)
node->m_right->m_parent = node->parent(); // ? node->parent() : m_null;
}
if (node->isBlack())
{
eraseFixup(fixPara);
}
m_null->m_parent = 0;
delete node;
}
void eraseFixup(node_type* node)
{
while (node != m_root && node->isBlack())
{
node_type* parent = node->parent();
if (node == parent->left()) // node是左子女
{
node_type* sibling = parent->right();
if (sibling->isRed()) // 如果兄弟是红, 转为黑
{
sibling->setBlack();
parent->setRed();
leftRotate(parent);
sibling = parent->right();
}
if (sibling->left()->isBlack() && sibling->right()->isBlack())
{
node = parent;
sibling->setRed();
}
else
{
if (sibling->right()->isBlack())
{
sibling->left()->setBlack();
sibling->setRed();
rightRotate(sibling);
sibling = parent->right();
}
sibling->m_black = parent->m_black;
parent->setBlack();
sibling->right()->setBlack();
leftRotate(parent);
node = m_root;
}
}
else // node是右子女
{
node_type* sibling = parent->left();
if (sibling->isRed()) //
{
sibling->setBlack();
parent->setRed();
rightRotate(parent);
sibling = parent->left();
}
if (sibling->right()->isBlack() && sibling->left()->isBlack())
{
node = parent;
sibling->setRed();
}
else
{
if (sibling->left()->isBlack())
{
sibling->right()->setBlack();
sibling->setRed();
leftRotate(sibling);
sibling = parent->left();
}
sibling->m_black = parent->m_black;
parent->setBlack();
sibling->left()->setBlack();
rightRotate(parent);
node = m_root;
}
}
}
node->setBlack();
}
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- ovod.cn 版权所有 湘ICP备2023023988号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务