Red and Black Trees and 2-3 Trees

Posted by kokomo310 on Tue, 30 Jul 2019 07:51:48 +0200

Red and Black Tree (also a Binary Search Tree)
1. Each node is either red or black.
2. The root node is black.
3. Each leaf node (the last empty node) is black.
4. If a node is red, its child nodes are black.
5. From any node to the leaf node, the black node is the same.
6. Red-black trees are binary trees that keep "black balance"
7. The red nodes of the red-black tree are inclined to the left.
Red-black tree is equivalent to 2-3 tree
1.2-3 tree satisfies the basic properties of binary search tree
2. Nodes can store one or two elements
3. Each node has two or three children (two children, called two nodes, three children, called three nodes).
2-3 Tree Addition Elements
4.2-3 tree is an absolutely balanced tree (i.e. two-three-node fusion). In the binary search tree in front of us, we know that the element value of the left subtree must be less than the root node, and the value of the right subtree is larger than the root node. Therefore, we should follow this point when we add elements to the 2-3 tree, if it is a two-node, then when we add them. Direct programming of three nodes, if it is three nodes, it will become four nodes, four nodes will become three two nodes, in turn, analogy, maintain absolute balance, adding nodes will not be added to the empty location, from the root node to the leaf node.
1. If the insertion of three nodes is a leaf node, the father node is two nodes.
The inserted element is fused with the root node to form a three-node
2. If the insertion of three nodes is a leaf node, the father node is three nodes.
The insertion element is fused with the father node to form a four-node, the four nodes are split into three two-node, and then continue to fuse upwards, and so on.
The common code is as follows

	private static final boolean RED = true;
	private static final boolean BLACK = false;
	private class Node {
		public K key;
		public V value;
		public Node left, right;
		public boolean color;
		public Node(K key, V value) {
			this.key = key;
			this.value = value;
			left = null;
			right = null;
			color = RED; 
		}
	}

	private Node root;
	private int size;

	public RBTree() {
		root = null;
		size = 0;
	}

	public int getSize() {
		return size;
	}

	public boolean isEmpty() {
		return size == 0;
	}

Color reversal
Change black to red and red to black, similar to the four nodes of a 2-3 tree
The specific implementation code is as follows

//Color reversal
	private void filpColor(Node node) {
		node.color = RED;
		node.left.color = BLACK;
		node.right.color = BLACK;
	}

Right rotation
Connect the right subtree of the child node to the left subtree of the father node, then connect the father node to the right subtree of the child node, change the father node to red, and the child node to black (color reversal) as follows

	//Right Rotation of Red-Black Trees
	private Node rightRotate(Node node) {
		Node x = node.left;
		//Right rotation
		node.left = x.right;
		x.right = node;

		x.color = node.color;
		node.color = RED;

		return x;
	}

Left rotation
Connect the left subtree of the child node to the right subtree of the father node, then connect the father node to the left subtree of the child node, turn the father node into red, and turn the child node into black (color inversion).

	//Left rotation of red-black trees
	private Node leftRotate(Node node) {
		
		Node x = node.right;
		//Left rotation
		node.right  =x.left;
		x.left = node;
		
		x.color = node.color;
		node.color = RED;
		
		return x;
	}

The three nodes of the 2-3 tree are equivalent to the father-child node in the red-black tree. The larger number of the three nodes is the father node, and the smaller number is the child node.
Red and Black Trees Add New Elements (Always Add Red Nodes)
Similar to adding new elements in 2-3, if the tree is empty, add directly, then turn red to black (color flip), if not, directly like adding elements in 2-3 tree, change the root node to black, the child node to red, if the added elements are in the left subtree, add directly, if in the right subtree, We need to rotate left and swap nodes at the same time. If we add elements between 2-3 tree nodes, we need to rotate children left, father nodes right, and finally color flip.
1. The right child is the red node, the left child is not the red node. (Rotate left, color flip)
2. The left child is the red node and the left child is the red node.
3. Both left and right children are red nodes.
The specific implementation code is as follows:

// Insert elements (key,value) into the red-black tree rooted by node, recursive algorithm
	// Returns the root of the red-black tree after inserting a new node
	private Node add(Node node, K key, V value) {
		if (node == null) {
			size++;
			return new Node(key, value);//Insert red node by default
		}

		if (key.compareTo(node.key) < 0) {
			node.left = add(node.left, key, value);
		} else if (key.compareTo(node.key) > 0) {
			node.right = add(node.right, key, value);
		} else {
			node.value = value;
		}
		//Maintenance of Red and Black Trees
		if(isRed(node.right) && !isRed(node.left)) {
			node = leftRotate(node);
		}
		if(isRed(node.left) && isRed(node.left.left)) {
			node = rightRotate(node);
		}
		if(isRed(node.left) && isRed(node.right)) {
			flipColor(node);
		}
		return node;
	}

Performance summary of red-black tree
1. For completely random data, ordinary binary search tree is very useful.
Disadvantage: Extreme cases degenerate into linked lists (or highly unbalanced)
2. AVL tree is very useful for more queries.
3. Red-black trees sacrifice balance and have better statistical performance.
Above is my understanding of red and black trees and 2-3 trees, do not like spraying, thank you!

Topics: less Programming