写在前面
C++Primer学到了关联式容器,该章相对于其他章节,讲述的比较简单,所以就打算实现RBtree来深刻体会关联式容器的底层工作原理。
存在的问题
1.子树左旋或右旋后,该子树的根指针指向正确,但其子树的根节点指向该子树的指针未改变。
2.动态内存学艺不精,内存分配这块,还存在很大问题,正在考虑使用智能指针(等我12、13章学完了再改正)。
3.代码冗余性过多,特别是if语句嵌套过多。
4.数据只接受int类型,未使用模板。
5.没有自定义的迭代器
第1-3点,是我必须要改正的!
第4以及第5点,需要认真阅读源码,之后达到实现其核心功能的目标。
路漫漫其修远兮!!!
希望大家监督,不断完善
下面是代码:
RB_Tree.h
class RB_Node;
using Tree = RB_Node * ;
const bool RED = true;
const bool BLACK = false;
class RB_Node
{
public:
RB_Node() = delete;
RB_Node(const int &data);
RB_Node(RB_Node &node);
~RB_Node() {}
public:
Tree left_xuan(Tree &node);
Tree right_xuan(Tree &node);
Tree adddata(const int &data, Tree presentnode);
Tree adddata(const int &data);
int getnode()const { return data; }
Tree checktree(Tree node);
Tree hasuncle(Tree node);
Tree nouncle(Tree node);
Tree checkrootr_b(Tree node);
private:
int data; //这里未来改成模板
Tree parent;
Tree l_child;
Tree r_child;
bool r_b = RED;
bool hasuse = false;
};
RB_Tree.cpp
#include"RB_tree.h"
RB_Node::RB_Node(const int &data)
{
this->data = data;
this->hasuse = true;
}
RB_Node::RB_Node(RB_Node& node)
{
this->data = node.data;
this->l_child = node.l_child;
this->r_child = node.r_child;
this->parent = node.parent;
this->hasuse = node.hasuse;
}
Tree RB_Node::left_xuan(Tree &oldhead)
{
Tree old(oldhead);
Tree newhead(oldhead->r_child);
Tree newheadrightchildcopy(newhead->l_child);
newhead->l_child = old;
newhead->parent = old->parent;
old->parent = newhead;
if (newheadrightchildcopy)
{
old->r_child = newheadrightchildcopy;
newheadrightchildcopy->parent = old;
}
else
old->r_child = nullptr;
return newhead;
}
Tree RB_Node::right_xuan(Tree &oldhead)
{
Tree old(oldhead);
Tree newhead(oldhead->l_child);
Tree newheadrightchildcopy(newhead->r_child);
newhead->r_child = old;
newhead->parent = old->parent;
old->parent = newhead;
if (newheadrightchildcopy)
{
old->l_child = newheadrightchildcopy;
newheadrightchildcopy->parent = old;
}
else
old->l_child = nullptr;
return newhead;
}
Tree RB_Node::adddata(const int &data, Tree presentnode)
{
if (presentnode->hasuse)
if (presentnode->data <= data)
{
if (presentnode->r_child)
{
presentnode = presentnode->r_child;
adddata(data, presentnode);
}
else
{
presentnode->r_child = new RB_Node(data);
presentnode->r_child->parent = presentnode;
presentnode = presentnode->r_child;
return presentnode;
}
}
else
{
if (presentnode->l_child)
{
presentnode = presentnode->l_child;
adddata(data, presentnode);
}
else
{
presentnode->l_child = new RB_Node(data);
presentnode->l_child->parent = presentnode;
presentnode = presentnode->l_child;
return presentnode;
}
}
}
Tree RB_Node::adddata(const int &data)
{
//adddata(data, this);
return checktree(adddata(data, this));
}
Tree RB_Node::checktree(Tree node)
{
if (node->parent!=nullptr)
{
while (node->parent->r_b == RED)
{
if (node->parent->parent)
if (node->parent->parent->r_child &&
node->parent->parent->l_child)
{
node = hasuncle(node);
if (node->parent==nullptr)
break;
}
else
{
node = nouncle(node);
if (node->parent == nullptr)
break;
}
else
break;
}
}
node = checkrootr_b(node); //检查根节点颜色
return node;
}
Tree RB_Node::hasuncle(Tree node)
{
if (node->parent->parent->r_child)
{
if (node->parent == node->parent->parent->l_child)
{
if (node->parent->parent->r_child->r_b == RED)
{
node->parent->r_b = BLACK;
node->parent->parent->r_child->r_b = BLACK;
node->parent->parent->r_b = RED;
node = node->parent->parent;
}
else if (node == node->parent->r_child)
{
node = left_xuan(node->parent)->l_child;
}
else
{
node->parent->r_b = BLACK;
node->parent->parent->r_b = RED;
Tree p = node->parent->parent->parent;
if(p)
if (node->parent->parent == p->r_child)
{
node = right_xuan(node->parent->parent);
node->parent = p->r_child;
}
else
{
node = right_xuan(node->parent->parent);
node->parent = p->l_child;
}
node = right_xuan(node->parent->parent);
}
}
else
{
if (node->parent->parent->l_child->r_b == RED)
{
node->parent->r_b = BLACK;
node->parent->parent->r_child->r_b = BLACK;
node->parent->r_b = RED;
node = node->parent->parent;
}
else if (node == node->parent->l_child)
{
node = right_xuan(node->parent)->r_child;
}
else
{
node->parent->r_b = BLACK;
node->parent->parent->r_b = RED;
node = left_xuan(node->parent->parent);
}
}
}
return node;
}
Tree RB_Node::nouncle(Tree node)
{
if (node->parent == node->parent->parent->l_child)
{
node->parent->r_b = BLACK;
node->parent->parent->r_b = RED;
Tree p = node->parent->parent->parent;
if (node == node->parent->l_child)
{
node = right_xuan(node->parent->parent);
}
else
{
node = left_xuan(node->parent);
node = right_xuan(node->parent);
}
}
else
{
if (node == node->parent->r_child)
node = left_xuan(node->parent->parent);
else
{
node = right_xuan(node->parent);
node = left_xuan(node->parent);
}
}
return node;
}
Tree RB_Node::checkrootr_b(Tree node)
{
while (node->parent)
node = node->parent;
if (node->r_b == RED)
node->r_b = BLACK;
return node;
}
main.cpp
#include"RB_tree.h"
int main()
{
RB_Node *p=new RB_Node(10);
p = p->adddata(5);
p = p->adddata(3);
p = p->adddata(2);
p = p->adddata(0);
return 0;
}