红黑树c++
作者:互联网
红黑树
具体的参考资料:
链接:https://pan.baidu.com/s/1Vgqo7_-yL_6hbxKknqaWRA
提取码:ozw6
#define BLACK 1
#define RED 0
#include <iostream>
using namespace std;
class bst
{
private:
struct Node
{
//节点的值
int value;
bool color;
Node *leftTree, *rightTree, *parent;
Node() : value(0), color(RED), leftTree(nullptr), rightTree(nullptr), parent(nullptr)
{
}
//返回节点的祖父
Node *grandparent()
{
if (parent == nullptr)
{
return nullptr;
}
return parent->parent;
}
//返回节点的叔叔
Node *uncle()
{
if (grandparent() == nullptr)
{
return nullptr;
}
if (parent == grandparent()->rightTree)
{
return grandparent()->leftTree;
}
else
{
return grandparent()->rightTree;
}
}
//返回节点的兄弟
Node *sibling()
{
if (parent->leftTree == this)
{
return parent->rightTree;
}
else
{
return parent->leftTree;
}
}
};
//右旋转
void rotate_right(Node *p)
{
Node *gp = p->grandparent();
Node *fa = p->parent;
Node *y = p->rightTree;
fa->leftTree = y;
if (y != NIL)
{
y->parent = fa;
}
p->rightTree = fa;
fa->parent = p;
if (root == fa)
{
root = p;
}
p->parent = gp;
if (gp != nullptr)
{
if (gp->leftTree == fa)
{
gp->leftTree = p;
}
else
{
gp->rightTree = p;
}
}
}
//左旋转
void rotate_left(Node *p)
{
if (p->parent == nullptr)
{
root = p;
return;
}
Node *gp = p->grandparent();
Node *fa = p->parent;
Node *y = p->leftTree;
fa->rightTree = y;
if (y != NIL)
{
y->parent = fa;
}
p->leftTree = fa;
fa->parent = p;
if (root == fa)
{
root = p;
}
p->parent = gp;
if (gp != nullptr)
{
if (gp->leftTree == fa)
{
gp->leftTree = p;
}
else
{
gp->rightTree = p;
}
}
}
//遍历
void inorder(Node *p)
{
if (p == NIL)
{
return;
}
if (p->leftTree)
{
inorder(p->leftTree);
}
cout << p->value << " ";
if (p->rightTree)
{
inorder(p->rightTree);
}
}
//输出颜色
string outputColor(bool color)
{
return color ? "BLACK" : "RED";
}
//得到最小的孩子
Node *getSmallestChild(Node *p)
{
if (p->leftTree == NIL)
{
return p;
}
return getSmallestChild(p->leftTree);
}
//删除孩子
bool delete_child(Node *p, int data)
{
if (p->value > data)
{
if (p->leftTree == NIL)
{
return false;
}
//如果要删除的值比当前节点的小,就一直向左子树走
return delete_child(p->leftTree, data);
}
else if (p->value < data)
{
if (p->rightTree == NIL)
{
return false;
}
//如果要删除的值比当前节点的大,就一直向右子树走
return delete_child(p->rightTree, data);
}
else if (p->value == data)
{
//如果找到要删除的节点,判断右子树是否存在,如果不存在,那么该节点最多就只有一个字节点
if (p->rightTree == NIL)
{
delete_one_child(p);
return true;
}
//如果右子树存在就在右子树中找到最小的节点,与要删除的节点,交换值,但是不交换颜色,不破坏红黑数的结构
Node *smallest = getSmallestChild(p->rightTree);
swap(p->value, smallest->value);
//删除这个最多只有一个孩子的节点
delete_one_child(smallest);
return true;
}
else
{
return false;
}
}
void delete_one_child(Node *p)
{
Node *child = p->leftTree == NIL ? p->rightTree : p->leftTree;
//只有根节点的情况
if (p->parent == nullptr && p->leftTree == NIL && p->rightTree == NIL)
{
if (p != nullptr)
{
delete p;
}
p = nullptr;
root = p;
return;
}
//只有根节点加上左子树或者右子树
if (p->parent == nullptr)
{
delete p;
child->parent = nullptr;
root = child;
root->color = BLACK;
return;
}
//将子节点上移,用子节点的代替要删除的节点
if (p->parent->leftTree == p)
{
p->parent->leftTree = child;
}
else
{
p->parent->rightTree = child;
}
child->parent = p->parent;
if (p->color == BLACK)
{
//如果要删除的是黑色的节点,并且孩子是红色的,那么就直接让孩子节点变成黑色就直接达到平衡
if (child->color == RED)
{
child->color = BLACK;
}
else
{
delete_case(child);
}
}
delete p;
}
void delete_case(Node *p)
{
if (p->parent == nullptr)
{
p->color = BLACK;
return;
}
//情形2
if (p->sibling()->color == RED)
{
p->parent->color = RED;
p->sibling()->color = BLACK;
if (p == p->parent->leftTree)
{
rotate_left(p->parent);
}
else
{
rotate_right(p->parent);
}
}
//情形3
if (p->parent->color == BLACK && p->sibling()->color == BLACK && p->sibling()->leftTree->color == BLACK && p->sibling()->rightTree->color == BLACK)
{
p->sibling()->color = RED;
delete_case(p->parent);
}
//情形4
else if (p->parent->color == RED && p->sibling()->color == BLACK && p->sibling()->leftTree->color == BLACK && p->sibling()->rightTree->color == BLACK)
{
p->sibling()->color = RED;
p->parent->color = BLACK;
}
else
{
//情形5
if (p->sibling()->color == BLACK)
{
if (p == p->parent->leftTree && p->sibling()->leftTree->color == RED && p->sibling()->rightTree->color == BLACK)
{
p->sibling()->color = RED;
p->sibling()->leftTree->color = BLACK;
rotate_right(p->sibling()->leftTree);
}
else if (p == p->parent->rightTree && p->sibling()->leftTree->color == BLACK && p->sibling()->rightTree->color == RED)
{
p->sibling()->color = RED;
p->sibling()->rightTree->color = BLACK;
rotate_left(p->sibling()->rightTree);
}
}
p->sibling()->color = p->parent->color;
p->parent->color = BLACK;
//情形6
if (p == p->parent->leftTree)
{
p->sibling()->rightTree->color = BLACK;
rotate_left(p->sibling());
}
else
{
p->sibling()->leftTree->color = BLACK;
rotate_right(p->sibling());
}
}
}
void insert(Node *p, int data)
{
if (p->value >= data)
{
if (p->leftTree != NIL)
{
insert(p->leftTree, data);
}
else
{
Node *tmp = new Node();
tmp->value = data;
tmp->leftTree = tmp->rightTree = NIL;
tmp->parent = p;
p->leftTree = tmp;
insert_case(tmp);
}
}
else
{
if (p->rightTree != NIL)
{
insert(p->rightTree, data);
}
else
{
Node *tmp = new Node();
tmp->value = data;
tmp->leftTree = tmp->rightTree = NIL;
tmp->parent = p;
p->rightTree = tmp;
insert_case(tmp);
}
}
}
void insert_case(Node *p)
{
//情形1 新节点N位于数的根上, 没有父节点
if (p->parent == nullptr)
{
root = p;
p->color = BLACK;
return;
}
if (p->parent->color == RED)
{
//情形3 父节点和叔父节点都是红色
if (p->uncle()->color == RED)
{
p->parent->color = p->uncle()->color = BLACK;
p->grandparent()->color = RED;
insert_case(p->grandparent());
}
else
{
//情形4 父节点是红色,叔父节点是黑色,并且插入的节点是父节点的右孩子, 父亲是祖父节点的左孩子
if (p->parent->rightTree == p && p->grandparent()->leftTree == p->parent)
{
rotate_left(p);
rotate_right(p);
p->color = BLACK;
p->leftTree->color = p->rightTree->color = RED;
}
//情形4 父节点是红色,叔父节点是黑色,并且插入的节点是父节点的左孩子, 父亲是祖父节点的右孩子
else if (p->parent->leftTree == p && p->grandparent()->rightTree == p->parent)
{
rotate_right(p);
rotate_left(p);
p->color = BLACK;
p->leftTree->color = p->rightTree->color = RED;
}
//情形4 父节点是红色,叔父节点是黑色,并且插入的节点是父节点的左孩子, 父亲是祖父节点的左孩子
else if (p->parent->leftTree == p && p->grandparent()->leftTree == p->parent)
{
p->parent->color = BLACK;
p->grandparent()->color = RED;
rotate_right(p->parent);
}
//情形4 父节点是红色,叔父节点是黑色,并且插入的节点是父节点的右孩子, 父亲是祖父节点的右孩子
else if (p->parent->rightTree == p && p->grandparent()->rightTree == p->parent)
{
p->parent->color = BLACK;
p->grandparent()->color = RED;
rotate_left(p->parent);
}
}
}
}
void DeleteTree(Node *p)
{
if (!p || p == NIL)
{
return;
}
DeleteTree(p->leftTree);
DeleteTree(p->rightTree);
delete p;
}
public:
bst()
{
NIL = new Node();
NIL->color = BLACK;
root = nullptr;
}
~bst()
{
if (root)
DeleteTree(root);
delete NIL;
}
void inorder()
{
if (root == nullptr)
return;
inorder(root);
cout << endl;
}
void insert(int x)
{
//第一次插入
if (root == nullptr)
{
root = new Node();
root->color = BLACK;
root->leftTree = root->rightTree = NIL;
root->value = x;
}
else
{
insert(root, x);
}
}
bool delete_value(int data)
{
return delete_child(root, data);
}
private:
Node *root, *NIL;
};
int main()
{
bst tree;
int array[] = {13, 8, 17, 1, 11, 15, 25, 6, 22, 27};
for (int i = 0; i < 10; i++)
{
tree.insert(array[i]);
}
tree.inorder();
cout << "--------------------------" << endl;
tree.delete_value(17);
tree.inorder();
}
标签:Node,rightTree,parent,color,c++,红黑树,leftTree,节点 来源: https://blog.csdn.net/qq_43812167/article/details/113811228