How to insert a node in a red-black tree
A red-black tree is a type of self-balancing binary tree. We'll learn how to make an insertion in a red-black tree using Python.
Note: If you want to learn more about a red-black tree, click here.
Algorithm
Insertion in a red-black tree is similar to a BST except for one additional step. The tree has to be recolored or rotated after inserting the node. A new node is always colored red initially.
First, we check if the root is
None. If it is, insert the new node and recolor it to black.If the root is not
None, go through the tree in such a way that if thevalueof a node is less than thevalueof the new node, move to its left child. Otherwise, move to its right child.Once we reach a leaf node, insert the new node there.
Now check to see if any properties of the red-black tree are violated. If they are, make the necessary adjustments by balancing the tree, such as recoloring or rotating.
Let's start with an empty tree and use an illustration to specify how insertion works.
Code
class Node:def __init__(self, value):self.value = valueself.left = Noneself.right = Noneself.parent = Noneself.color = REDclass RedBlackTree:def __init__(self):self.root = Nonedef _insert(self, node, new_node):if node.value > new_node.value:if not node.left:node.left = new_nodenew_node.parent = nodeelse:self._insert(node.left, new_node)else:if not node.right:node.right = new_nodenew_node.parent = nodeelse:self._insert(node.right, new_node)def insert(self, new_val):new_node = Node(new_val)if not self.root:self.root = new_nodeself.root.color = BLACKelse:self._insert(self.root, new_node)self.balance(new_node)def balance(self, new_node):while new_node.parent and new_node.parent.color != BLACK:if new_node == self.root:breakparent = new_node.parentgrandparent = parent.parentif parent == grandparent.left:uncle = grandparent.rightif uncle and uncle.color == RED:uncle.color = BLACKparent.color = BLACKgrandparent.color = REDnew_node = grandparentelse:if new_node == parent.right:new_node = parentself.leftRotate(new_node)new_node.parent.color = BLACKnew_node.parent.parent.color = REDself.rightRotate(new_node.parent.parent)else:uncle = grandparent.leftif uncle and uncle.color == RED:uncle.color = BLACKparent.color = BLACKgrandparent.color = REDnew_node = grandparentelse:if new_node == parent.left:new_node = parentself.rightRotate(new_node)new_node.parent.color = BLACKnew_node.parent.parent.color = REDself.leftRotate(new_node.parent.parent)self.root.color = BLACKdef leftRotate(self, node):right_child = node.rightnode.right = right_child.leftif right_child.left:right_child.left.parent = nodeif not node.parent:self.root = right_childelif node.parent.left == node:node.parent.left = right_childelse:node.parent.right = right_childright_child.parent = node.parentright_child.left = nodenode.parent = right_childdef rightRotate(self, node):left_child = node.leftnode.left = left_child.rightif left_child.right:left_child.right.parent = nodeif not node.parent:self.root = left_childelif node.parent.left == node:node.parent.left = left_childelse:node.parent.right = left_childleft_child.parent = node.parentleft_child.right = nodenode.parent = left_childtree = RedBlackTree()tree.insert(7)tree.insert(13)tree.insert(20)tree.insert(31)tree.insert(3)tree.insert(33)print(" ", tree.root.value, tree.root.color)print(" / \\")print(" ", tree.root.left.value, tree.root.left.color, " ", tree.root.right.value, tree.root.right.color)print(" / / \\")print("", tree.root.left.left.value, tree.root.left.left.color, " ", tree.root.right.left.value, tree.root.right.left.color, " ", tree.root.right.right.value, tree.root.right.right.color)
Explanation
Lines 1–7: We define a class
Nodethat stores a single red-black tree node.Lines 13–17: We define a private function ,
_insert(), that inserts anew_nodein the tree. It is similar to insertion in a BST.Lines 36–72: We define the
balancefunction. It checks if there are two consecutive red nodes. If theuncleof theREDnode isBLACKorNone, then it rotates the tree. If theunclenode isRED, it changes the color of theparentandunclenodes toBLACKand then changes the color of thegrandparenttoRED. This process is repeated until there are no two consecutive red nodes or we reach the tree'sroot.Lines 74–106: We define the
leftRotate()andrightRotate()functions that rotate a node left and right in a tree, respectively. It follows the same algorithm as rotation in an AVL.Lines 108–119: We create a
tree, and print the resulting red-black tree.
Free Resources