Find -- Definition of Red-Black Tree

1. Definition: A red-black tree is a binary search tree, but each node adds a variable to identify the color of each node. We need this color to specify some rules about the red-black tree. We are constructing a red-black tree. When it comes to black trees, you need to keep these rules at all times:
1) Each node is either black or red
2) The root node is black
3) Each leaf node is black
4) No two red nodes are adjacent
5) For each node, the simple path from the node to all descendant leaf nodes contains the same number of black nodes.
We need to keep these five rules all the time, whether it is inserting nodes or deleting nodes, so that we have An approximately balanced search binary tree can be obtained.

Why is it said to be approximately balanced? Because the red-black tree is not like the AVL tree, the AVL tree is a height-balanced binary search tree. For each node, the heights of the left and right subtrees differ by at most 1, but the red-black tree is black-height balanced, that is, the fifth rule. A red-black tree ensures that no one path is twice as good as the others.


What we are more concerned about is the efficiency of the red-black tree: the red-black tree can guarantee that the insertion, search, and deletion operations can be completed in O(lgN) time in the worst case.

First, let's define nodes and colors:

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;
};

The node class is the same as the binary search tree, but with an additional color member.

Because the red-black tree adds color to the basis of the binary search tree, many operations of the binary search tree are retained. Next, we define the red-black tree class:

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;    //哨兵
};

In the above class definition, compared to the binary search tree, the following operations and members are added:

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;    //哨兵

Among them, adjustTree may call this function when inserting a node, because inserting a node may break one or more of the five rules of the red-black tree.
dealOneChild is a pointer to the parent pointer used to manipulate the two parameters.
adjustDelete is called when a node is deleted.
The sentinel is a special node, the color is always black, and the values ​​of other members are not specified. It acts as the parent node of the leaf node and the root node in the class (in fact, we can also use nullptr NULL and the like constants)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325917652&siteId=291194637