查找--红黑树的定义

1.定义:红黑树是一颗二叉查找树,但是每一个节点多加上了一个变量来标识每一个节点的颜色,我们需要这个颜色来规定一些关于红黑树的规则,我们在构造红黑树的时候,需要每个时候都要保持这些规则:
1)每个节点不是黑色就是红色
2)根节点为黑色
3)每个叶节点是黑色的
4)没有两个红色节点相邻
5)对于每一个节点,从该节点到期所有后代叶节点的简单路径上,都包含相同数目的黑色节点
我们需要一直保持着这五个规则,不管是插入节点,还是删除节点的时候,这样我们就可以得到一颗近似平衡的查找二叉树。

为什么说是近似平衡的?因为红黑树不像AVL树,AVL树是高度平衡的二叉查找树,对于每一个节点,左右子树的高度最多相差1,但是红黑树是黑高平衡的,即第五条规则。红黑树会确保没有一条路径会比其他路径长处2倍。


我们比较关心的是红黑树的效率问题:红黑树可以保证在最坏情况下都可以在O(lgN)的时间内完成插入,查找,删除操作。

首先,我们先定义节点和颜色:

enum COLOR {
    BLACK = 1,
    RED = 2,
};

template <class Key, class Value>
struct Node {
    Node(Key k, Value v) : key(k), value(v), color(RED), parent(NULL), left(NULL), right(NULL) {}
    Node() : color(BLACK), parent(NULL), left(NULL), right(NULL) {}
    ~Node() {}
    Key key;
    Value value;
    COLOR color;
    Node<Key, Value>* parent;
    Node<Key, Value>* left;
    Node<Key, Value>* right;
};

节点类跟二叉搜索树一样,但是多出了一个颜色成员。

因为红黑树是在二叉搜索树的基础上面加上了颜色,所以保留了很多二叉搜索树的操作,接下来我们定义红黑树类:

template <class Key, class Value>
class RBTree {
public:
    RBTree() : root(NULL) {NIL = new Node<Key, Value>();}
    ~RBTree() {}
    Node<Key, Value>* insert(Node<Key, Value>* node);
    void printTree();
    void erase(Key key);
    Node<Key, Value>* find(Key key);
private:
    void rotateLeft(Node<Key, Value>* node);
    void rotateRight(Node<Key, Value>* node);
    void adjustTree(Node<Key, Value>* node);
    void printTree(Node<Key, Value>* node);
    Node<Key, Value>* findNext(Node<Key, Value>* node);
    Node<Key, Value>* findMin(Node<Key, Value>* node);
    void dealOneChild(Node<Key, Value>* node, Node<Key, Value>* child);
    void adjustDelete(Node<Key, Value>* node, Node<Key, Value>* realParent);
    Node<Key, Value>* root;
    Node<Key, Value>* NIL;    //哨兵
};

在上面的类定义里面,相比于二叉搜索树来说,多出了以下的操作和成员:

void adjustTree(Node<Key, Value>* node);
void dealOneChild(Node<Key, Value>* node, Node<Key, Value>* child);
void adjustDelete(Node<Key, Value>* node, Node<Key, Value>* realParent);
Node<Key, Value>* NIL;    //哨兵

其中,adjustTree是在插入节点的时候可能会调用这个函数,因为插入节点可能会破坏红黑树的五条规则其中的一个或者几个。
dealOneChild是用来操作两个参数的父指针的指向。
adjustDelete是在删除一个节点的时候会调用。
哨兵是一个特殊的节点,颜色永远是黑色的,而且其他的成员取值没有特别规定,它在类中充当了叶节点和根节点的父节点的角色(其实我们也可以使用nullptr NULL之类的常量来表示)

猜你喜欢

转载自blog.csdn.net/nia305/article/details/78078357