红黑树 c++实现

来源:互联网 发布:ogg 中同步表数据变动 编辑:程序博客网 时间:2024/06/04 19:20

参考算法导论里的红黑树相关内容编写。

#include <iostream>

#include <cassert>
using namespace std;


#ifndef RBTREE_H
#define RBTREE_H


enum colortype{RED,BLACK};


template<typename datatype>
class rbtree_node{
public:
datatype data;
colortype color;
rbtree_node *parent;
rbtree_node *left;
rbtree_node *right;
rbtree_node(const datatype &dat, colortype cl, rbtree_node *p, rbtree_node *l, rbtree_node *r) :data(dat), color(cl), parent(p), left(l), right(r){}
rbtree_node(const datatype &dat) :data(dat), color(BLACK), parent(nullptr), left(nullptr), right(nullptr){}
rbtree_node() :data(0), color(BLACK), parent(nullptr), left(nullptr), right(nullptr){}
};




template<typename datetype>
class rbtree{
public:
rbtree() :tree_root(nullptr){}
~rbtree();
bool empty()const;
void inOder(ostream &out) const;
bool seartch(const datetype &item)const;
void insert(const datetype &item);
void remove(const datetype &item);
private:
rbtree_node<datetype> *tree_root;
rbtree_node<datetype>* return_parent(rbtree_node<datetype> *x);
bool is_red(rbtree_node<datetype> *x);
bool is_black(rbtree_node<datetype> *x);
void set_red(rbtree_node<datetype> *z);
void set_black(rbtree_node<datetype>*z);
void destroy(rbtree_node<datetype> *&root);
void inOder_aux(ostream &out, rbtree_node<datetype> *subtree_root)const;
rbtree_node<datetype>* seartch_aux(rbtree_node<datetype> *root, const datetype &item)const;
void leftRotation(rbtree_node<datetype> *&subtree_root, rbtree_node<datetype> *x);
void rightRotation(rbtree_node<datetype> *&subtree_root, rbtree_node<datetype> *x);
void insert_aux(rbtree_node<datetype> *&root, rbtree_node<datetype> *insert_node);
void remove_aux(rbtree_node<datetype> *&root, rbtree_node<datetype> *remove_node);
void remove_fixup(rbtree_node<datetype> *&root, rbtree_node<datetype> *z);
void insertFixup(rbtree_node<datetype> *&subtree_root, rbtree_node<datetype> *z);
rbtree_node<datetype>* treeSuccessor(rbtree_node<datetype> *z);
rbtree_node<datetype>* maxiumNode(rbtree_node<datetype> *z);
rbtree_node<datetype>* minimumNode(rbtree_node<datetype> *z);
};


template<typename datetype>
rbtree<datetype>::~rbtree()
{
destroy(tree_root);
}
template<typename datetype>
void rbtree<datetype>::destroy(rbtree_node<datetype> *&root)
{
if (root == nullptr)
return;
if (root->left != nullptr)
return destroy(root->left);
else if (root->right != nullptr)
return destroy(root->right);
delete root;
root = nullptr;
}
template<typename datetype>
inline bool rbtree<datetype>::empty()const
{
return tree_root == nullptr;
}


template<typename datetype>
rbtree_node<datetype>* rbtree<datetype>::return_parent(rbtree_node<datetype> *x)
{
if (x->parent != nullptr)
return x->parent;
return nullptr;
}


template<typename datetype>
rbtree_node<datetype>* rbtree<datetype>::maxiumNode(rbtree_node<datetype> *z)
{
while (z->right != nullptr)
z = z->right;
return z;
}


template<typename datetype>
rbtree_node<datetype>* rbtree<datetype>::minimumNode(rbtree_node<datetype> *z)
{
while (z->left!=nullptr)
{
z = z->left;
}
return z;
}


template<typename datetype>
rbtree_node<datetype>* rbtree<datetype>::treeSuccessor(rbtree_node<datetype> *z)
{
if (z->right != nullptr)
return minimumNode(z->right);
rbtree_node<datetype> *y = z->parent;
while (y != nullptr&&y->right == y)
{
z = y;
y = y->parent;
}
return y;
}


template<typename datetype>
bool rbtree<datetype>::is_red(rbtree_node<datetype> *x)
{
assert(x != nullptr);
return x->color == RED;
}


template<typename datetype>
bool rbtree<datetype>::is_black(rbtree_node<datetype> *x)
{
assert(x != nullptr);
return x->color == BLACK;
}


template<typename datetype>
void rbtree<datetype>::set_red(rbtree_node<datetype> *x)
{
if (x != nullptr)
x->color = RED;
}


template<typename datetype>
void rbtree<datetype>::set_black(rbtree_node<datetype> *x)
{
if (x != nullptr)
x->color = BLACK;
}
template<typename datetype>
void rbtree<datetype>::inOder_aux(ostream &out, rbtree_node<datetype> *subtree_root)const
{
if (subtree_root != nullptr)
{
inOder_aux(out, subtree_root->left);
out << subtree_root->data << " ->" << subtree_root->color << "->parent:";
if (subtree_root->parent != nullptr)
out << subtree_root->parent->data << endl;
else
out << endl;
inOder_aux(out, subtree_root->right);
}
}


template<typename datetype>
void rbtree<datetype>::inOder(ostream &out)const
{
inOder_aux(out, tree_root);
}


template<typename datetype>
void rbtree<datetype>::leftRotation(rbtree_node<datetype> *&subtree_root, rbtree_node<datetype> *x)
{
rbtree_node<datetype> *y = x->right;
x->right = y->left;
if (y->left != nullptr)
y->left->parent = x;
y->parent = x->parent;
if (x->parent == nullptr)
subtree_root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y;
}


template<typename datetype>
void rbtree<datetype>::rightRotation(rbtree_node<datetype> *&subtree_root, rbtree_node<datetype> *x)
{
rbtree_node<datetype> *y = x->left;
x->left = y->right;
if (y->right != nullptr)
y->right->parent = x;
y->parent = x->parent;
if (x->parent == nullptr)
subtree_root = y;
else if (x== x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->right =x;
x->parent = y;
}


template<typename datetype>
void rbtree<datetype>::insertFixup(rbtree_node<datetype> *&subtree_root, rbtree_node<datetype> *z)
{
rbtree_node<datetype> *p, *gp;
while (((p=z->parent)!=nullptr)&&p->color == RED)
{
cout << "进入循环\n";
cout << "父亲是:"<<p->data << endl;
gp = p->parent;
if (gp != nullptr)
cout << "当前节点祖先" << gp->data << endl;
else
cout << "无祖先\n";
if (p == gp->left)
{
cout << "父亲为祖先的左孩子\n";
rbtree_node<datetype> *y =gp->right;
if (y&&is_red(y))//case 1
{
cout << "case 1\n";
set_black(p);
set_black(y);
set_red(gp);
z =gp;
continue;//情况1与情况2、情况3是独立的,所以直接跳过后面结束此次循环
}
else if (z == p->right) //case 2
{
cout << "case 2\n";
leftRotation(subtree_root, p);
rbtree_node<datetype> *tmp=z;
z = p;
p = tmp;
}
//case 3 
cout << "case3\n";
set_black(p);
set_red(gp);
rightRotation(subtree_root, gp);
}
else//p是gp的右孩子
{
cout << "p是gp的右孩子\n";
rbtree_node<datetype> *y = gp->left;
if (y&&is_red(y))//case1 
{
cout << "case1\n";
set_black(y);
set_black(p);
set_red(gp);
z = gp;
continue;
}
else if (z == p->left)
{
cout << "case 2\n";
cout << "右旋开始\n";
rightRotation(subtree_root, p);
cout << "右旋结束\n";
rbtree_node<datetype> *tmp = z;
z = p;
p = tmp;
}
cout << "case3\n";
set_black(p);
set_red(gp);
leftRotation(subtree_root,gp);
}
}
set_black(subtree_root);
cout << z->color << endl;
}


template<typename datetype>
void rbtree<datetype>::insert_aux(rbtree_node<datetype> *&root, rbtree_node<datetype> *z)
{
rbtree_node<datetype> *y=nullptr;
rbtree_node<datetype> *x = root;
//cout << "x:"<<tree_root->data;
while (x != nullptr)
{
y = x;
if (z->data<x->data)
x = x->left;
else
x = x->right;
}
z->parent = y;
if (y == nullptr)
root = z;
else if (z->data < y->data)
y->left = z;
else
y->right = z;
z->color=RED;
cout << z->data<<"节点修正开始\n";
insertFixup(root, z);
cout << "修正结束\n";
}


template<typename datetype>
void rbtree<datetype>::insert(const datetype &item)
{
rbtree_node<datetype> *z = new rbtree_node<datetype>(item,BLACK,nullptr,nullptr,nullptr);
if (z == nullptr)
{
cerr << "插入失败";
return;
}
insert_aux(tree_root,z);
}




template<typename datetype>
rbtree_node<datetype>* rbtree<datetype>::seartch_aux(rbtree_node<datetype> *root, const datetype &item) const
{
rbtree_node<datetype> *locptr = root;
while (locptr != nullptr)
{
if (item < locptr->data)
locptr = locptr->left;
else if (item>locptr->data)
locptr = locptr->right;
else
return locptr;
}
return locptr;
}


template<typename datetype>
bool rbtree<datetype>::seartch(const datetype &item) const 
{
if (tree_root == nullptr)
{
cerr << "空树\n";
return false;
}
rbtree_node<datetype> *z = seartch_aux(tree_root, item);
if ( z!= nullptr)
return true;
return false;
}


template<typename datetype>
void rbtree<datetype>::remove(const datetype &item)
{
rbtree_node<datetype> *z = seartch_aux(tree_root, item);
if (z == nullptr)
{
cerr << "删除对象不存在于树中\n";
exit(1);
}
remove_aux(tree_root, z);
}


template<typename datetype>
void rbtree<datetype>::remove_aux(rbtree_node<datetype> *&root, rbtree_node<datetype> *remove_node)
{
rbtree_node<datetype> *y;
if (remove_node->left == nullptr || remove_node->right == nullptr)
{
y = remove_node;
}
else
y = treeSuccessor(remove_node);
cout << "删除节点:" << remove_node->data << endl;
cout << "后继节点:"<<y->data<<endl;
rbtree_node<datetype> *x;
if (y->left != nullptr)
x = y->left;
else
x = y->right;
if (x!=nullptr)
x->parent = y->parent;
cout << "将x的父亲变换为y的父亲\n";
if (y->parent == nullptr)
root = x;
else if (y == y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
if (y != remove_node)
{
cout << "将删除节点与其中序后继交换key\n";
remove_node->data = y->data;
}
if ((x!=nullptr)&&y->color == BLACK)//先检查调整点得指针是否为空
{
cout << "对红黑树进行调整\n";
remove_fixup(root, x);
cout << "调整完毕\n";
}
delete y;
}


template<typename datetype>
void rbtree<datetype>::remove_fixup(rbtree_node<datetype> *&root, rbtree_node<datetype> *x)
{
rbtree_node<datetype> *w = nullptr;
while (x != root&&x->color == BLACK)
{
if (x == x->parent->left)
{
cout << "x为父亲节点的左孩子\n";
w = x->parent->right;
if (is_red(w))//case1
{
cout << "case1\n";
set_black(w);
leftRotation(root, x->parent);
w = x->parent->right;
}
if (is_black(w->left) && is_black(w->right))//case2
{
cout << "case2 \n";
set_red(w);
x = x->parent;
}
else if (is_black(w->right))//case 3
{
cout << "case 3 \n";
set_black(w->left);
set_red(w);
rightRotation(root, w);
w = x->parent->right;
}
//case4
cout << "case 4\n";
w->color = x->parent->color;
set_black(x->parent);
set_black(w->right);
leftRotation(root, x->parent);
x = root;
}
else
{
cout << "x为父亲节点的右孩子\n";
w = x->parent->left;
if (is_red(w))
{
cout << "case 1\n";
set_black(w);
rightRotation(root, x->parent);
w = x->parent->left;
}
if (is_black(w->left) && is_black(w->right))
{
cout << "case 2\n";
set_red(w);
x = x->parent;
}
else if (is_black(w->left))
{
cout << "case 3\n";
set_black(w->right);
set_red(w);
leftRotation(root, w);
w = x->parent->left;
}
cout << "case 4\n";
w->color = x->parent->color;
set_black(x->parent);
set_black(w->left);
leftRotation(root, x->parent);
x = root;
}
}
set_black(x);
}


#endif
0 0