A brief discussion on the algorithm and data structure: Nine balance search tree of red and black trees

Source: Internet
Author: User
Tags reflector

The previous article introduced the 2-3 lookup tree, you can see that the 2-3 find tree can ensure that after inserting elements can maintain the balance of the tree, the worst case is all the child nodes are 2-node, the height of the tree is LGN, thus guaranteeing the worst case of time complexity. However, 2-3 trees are more complex to implement, this paper introduces a simple implementation of 2-3 tree data structure, that is, red-black trees (red-black tree)

Defined

The red and black trees are mostly like encoding the 2-3 lookup tree, especially adding additional information to the 3-nodes node in the 2-3 lookup tree. The red-black tree divides the links between nodes into two different types, the red link, which he uses to link two 2-nodes nodes to represent a 3-nodes node. A black link is used to link a normal 2-3 node. In particular, two 2-nodes with red links are used to represent a 3-nodes node, and to the left, where one 2-node is the left child node of another 2-node. The advantage of this approach is that you don't have to make any changes when looking for the same as a normal two-fork lookup tree.

According to the above description, the red and black tree is defined as follows:

The red-black tree is a balanced lookup tree with red and black links, while satisfying:

    • Red nodes Tilt Left
    • A node cannot have two red links
    • The whole book is completely black balanced, that is, from the root node to the path of the leaf node, the number of black links is the same.

You can see that the red and black trees are actually another form of expression for the 2-3 trees: if we draw the red line horizontally, then the two 2-node nodes that he links are a 3-node node in the 2-3 tree.

Said

We can add a new token representing the color on each node of the binary lookup tree. The flag indicates the color that the node points to its parent node.

Private Const BOOL RED = True;private const BOOL BLACK = false;private node root;class node{public    Node left {get; s Et Public    Node Right {get; set;}    Public TKey Key {get; set;}    Public TValue Value {get; set;}    public int number {get; set;}    public bool Color {get; set;}    Public Node (TKey key, TValue value,int number, bool color)    {this        . key = key;        This. value = value;        This. Number = number;        This. color = color;    }} private bool Isred (node node) {    if (node = = null) return false;    Return node. Color = = RED;}

Implementation Lookup

The red and black tree is a special two-fork search tree, and his search method is the same as a two-fork search tree, so there is no need to make too many changes.

But because the red and black trees have a better balance than the average two-fork search tree, it is quicker to find them.

Lookup gets the specified value public override TValue Get (TKey key) {    return GetValue (root, key);} Private TValue GetValue (node node, TKey key) {    if (node = = NULL) return to default (TValue);    int cmp = Key.compareto (node. Key);    if (cmp = = 0) return node. Value;    else if (CMP > 0) return GetValue (node. Right, key);    else return GetValue (node. Left, key);}
Balance of

Before we introduce the INSERT, let's show how to keep the red-black tree balanced, because in general, after we insert it, we need to balance the tree to make it fit.

Rotate

Spin is divided into left and right . A left-hand operation is typically used to rotate a red link that tilts to the right to a left link. Before and after the contrast operation, it can be seen that the operation is actually moving a large node in the two nodes of the Red line link to the root node.

L-Operations such as:

Left Rotate private node Rotateleft (node h) {    node x = h.right;    The left node of x is copied to h right node    h.right = X.left;    Copy h to x right node    x.left = h;    X.color = H.color;    H.color = RED;    return x;}

The left-handed animation works as follows:

The right-hand is the inverse of the left-handed operation, as follows:

The code is as follows:

Right rotation private node Rotateright (node h) {    node x = h.left;    H.left = x.right;    X.right = h;    X.color = H.color;    H.color = RED;    return x;}

Right-handed animations are as follows:

Color reversal

When a temporary 4-node occurs, the two child nodes of a node are red, such as:

This is actually a a,e,s 4-node connection, we need to promote E to the parent node, the operation method is very simple, is to set the e-node connection to black, and its own color set to red.

With these basic operations in hand, we now balance the red and black trees with the previous balancing operation on the 2-3 tree, which can correspond to each other, such as:

Now to discuss the various situations:

Case 1 Towards a 2-node Insert a new node at the bottom of the node

First of all, let's look at the action of inserting a new node for a red-black tree with only one node:

This is a simple situation and requires only:

    • Standard two-fork lookup tree traversal. The newly inserted node is marked red
    • If the newly inserted node is on the right child node of the parent node, a left-hand operation is required

Case 2 Towards a 3-node Insert a new node at the bottom of the node

To warm up first, let's say we insert elements into a tree with only two nodes, such as the size of the element to be inserted and the existing element, and can be divided into the following three cases:

    • This is easiest if the node with the insertion is larger than the existing two nodes. We just need to connect the newly inserted node to the right subtree, then elevate the middle element to the root node. So the root node of the left and right subtree are red nodes, we only need to investigate the Flipcolor method. Other cases are reversed and will be the same.
    • If the inserted node is smaller than the smallest element, then add the new node to the leftmost, so there are two nodes that are connected to the red node, which is the right-hand operation of the middle node, making the intermediate nodes the root node. This translates to the first case where only one more flipcolor operation is required.
    • If the value of the inserted node is between two nodes, the new node is inserted into the right child node of the left node. Because the right child node of the node is red, a left-hand operation is required. After the operation has become the second case, then the right-hand, and then call the Flipcolor operation to complete the balance operation.

With the above basics, let's summarize the steps to insert a new node at the bottom of a 3-node node, which is a typical operating procedure diagram:

As you can see, the procedure is as follows:

    1. Performs a standard two-fork find tree insert operation, with the newly inserted node element identified in red.
    2. If you need to rotate the 4-node node
    3. If necessary, call the Flipcolor method to elevate the red node
    4. If necessary, the left-hand operation causes the red node to leave.
    5. In some cases, a recursive call to Case1 Case2 is required to perform a recursive operation. As follows:

Code implementation

After the balanced discussion above, it is time to implement the insert operation, and the general insert operation is to perform a standard two-fork lookup tree Insert before balancing. Compared with 2-3 trees, we can complete the balance through the three kinds of operation, which are discussed above, left-hand, right-handed and flipcolor.

Here's how it works:

    • If the right child node of the node is red, and the left child node is black, the left-hand operation
    • If the left child node of a node is red and the left child node of the left child node is also red, the right-handed operation
    • If the left and right child nodes of the node are red, the Flipcolor operation is performed to promote the intermediate junction.

Based on this logic, we can implement the put method of inserting.

public override void put (TKey key, TValue value) {    root = Put (root, key, value);    Root. Color = BLACK;} Private node Put (node H, TKey key, TValue value) {    if (h = = null) return new Node (key, value, 1, RED);    int cmp = Key.compareto (h.key);    if (CMP < 0) H.left = Put (H.left, key, value);    else if (cmp > 0) h.right = Put (H.right, key, value);    else H.value = Value;    Balanced Operation    if (isred (h.right) &&! Isred (h.left)) H = rotateleft (h);    if (isred (h.right) && isred (h.left.left)) H = rotateright (h);    if (isred (h.left) && isred (h.right)) H = Flipcolor (h);    H.number = Size (h.left) + size (h.right) + 1;    return h;} private int Size (node node) {    if (node = = null) return 0;    Return node. number;}
Analysis

The analysis of the red and black tree is actually the analysis of 2-3 search tree, the red and black tree can ensure that all the operation of the symbol table in the worst case can guarantee the logarithmic time complexity, that is, the height of the tree.

Before analyzing, to be more intuitive, here is an animation of a red-black tree in ascending, descending, and random form:

    • To build a red-black tree in ascending order:

    • To build a red-black tree in descending order:

    • Randomly inserted to build a red-black tree

From the above three animation effects, it can be very intuitive to see that the red and black trees in various situations can maintain good balance, so as to ensure the worst case of the search, insertion efficiency.

Below is a detailed analysis of the efficiency of the red and black trees:

1. In the worst case, the height of the red-black tree does not exceed 2lgN

The worst case scenario is that the red and black trees, except for the leftmost path, are all made up of 3-node nodes, that is, the red and black path length is 2 times the length of the full black path .

is a typical red-black tree from which you can see the longest path (the red-black path) is twice times the shortest path:

2. The average height of the red and black trees is about LGN

Is the time complexity of the red and black trees in various cases, it can be seen that the red and black tree is an implementation of the 2-3 search tree, he can ensure that the worst case still has a logarithmic time complexity.

Is the time complexity of the various operations of the red and black trees.

Application

Red and black tree This data structure is widely used in many programming languages as a symbol table implementation, such as:

    • Java.util.treemap,java.util.treeset in Java
    • C + + STL: Map,multimap,multiset
    • . NET: Sorteddictionary,sortedset, etc.

Below with. NET as an example, through the reflector tool, we can see that the Add method of SortedDictionary is as follows:

public void Add (T item) {if (this.root = = null) {this.root = new node<t> (item, FALSE);    This.count = 1;        } else {node<t> root = this.root;        node<t> node = null;        Node<t> grandparent = null;        Node<t> greatgrandparent = null;        int num = 0; while (root = null) {num = This.comparer.Compare (item, root.            Item);                if (num = = 0) {this.root.IsRed = false;            Throwhelper.throwargumentexception (exceptionresource.argument_addingduplicate); } if (Treeset<t>. Is4node (root) {treeset<t>.                Split4node (root); if (TREESET&LT;T&GT;. Isred (node)) {this.                Insertionbalance (Root, ref node, grandparent, greatgrandparent);            }} greatgrandparent = grandparent;            grandparent = node; node = root;            root = (num < 0)? Root. Left:root.        right;        } node<t> current = new node<t> (item); if (num > 0) {node.        right = current; } else {node.        left = current; } if (node. isred) {this.        Insertionbalance (Current, ref node, grandparent, greatgrandparent);        } this.root.IsRed = false;        this.count++;    this.version++; }}

As you can see, the internal implementation is also a red-black tree, its operation method and this article will be similar, interested in words, you can use the Reflector tool to follow up to see the source code.

Summarize

This article explains the 2-3 lookup tree in the self-balancing lookup tree, which can be self-balanced after insertion, thus ensuring that the height of the tree is within a certain range to ensure the worst-case time complexity. But the 2-3 find tree is difficult to implement, and the red-black tree is a simple and efficient implementation of 2-3 trees, and he cleverly uses color tags instead of the more difficult-to-handle 3-node node problem in 2-3 trees. Red-black tree is a relatively efficient and balanced search tree, the application is very extensive, many of the internal implementation of programming languages are more or less the use of red and black trees.

I hope this article will help you understand the red and black trees, and the following is an introduction to another balanced tree structure that is widely used in file systems and database systems: B-Tree

A brief discussion on the algorithm and data structure: Nine balance search tree of red and black trees

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.