enumColor { // Defines an enum called 'Color' Red, // Enum variant representing the color red Black, // Enum variant representing the color black } structNode<K, V> { // Defines a struct called 'Node' with generic parameters 'K' and 'V' key: K, // Field representing the key of the node value: V, // Field representing the value of the node color: Color, // Field representing the color of the node, which is of type 'Color' enum left: Option<Box<Node<K, V>>>, // Field representing the left child node of the current node (if exists); it is an Option type and wrapped inside a box right: Option<Box<Node<K, V>>>, // Field representing the right child node of the current node (if exists); it is an Option type and wrapped inside a box }
pubstructRBTree<K: Ord, V> { // Defines a struct called 'RBTree' with generic parameters 'K' and 'V'; 'K' must implement 'Ord' trait root: Option<Box<Node<K, V>>>, // Field representing the root node of the red-black tree; it is an Option type and wrapped inside a box }
// Defines a private method called 'rotate_left' that takes a mutable reference to a 'Node' struct fnrotate_left(mut node: &mut Node<K, V>) { // Takes ownership of the right child node of the given node letmut right = node.right.take().unwrap(); // Moves the left child of the right child node to the right child of the given node node.right = right.left.take(); // Sets the parent of the right child node as the given node and returns the right child node right.left = Some(std::mem::replace(&mut node, right)); // Sets the parent of the left child node of the given node to the given node ifletSome(refmut left) = node.left { left.parent = Some(node); } // Sets the parent of the right child node of the given node to the given node ifletSome(refmut right) = node.right { right.parent = Some(node); } // Updates the size of the given node node.update_size(); }
// Defines a private method called 'rotate_right' that takes a mutable reference to a 'Node' struct fnrotate_right(mut node: &mut Node<K, V>) { // Takes ownership of the left child node of the given node letmut left = node.left.take().unwrap(); // Moves the right child of the left child node to the left child of the given node node.left = left.right.take(); // Sets the parent of the left child node as the given node and returns the left child node left.right = Some(std::mem::replace(&mut node, left)); // Sets the parent of the left child node of the given node to the given node ifletSome(refmut left) = node.left { left.parent = Some(node); } // Sets the parent of the right child node of the given node to the given node ifletSome(refmut right) = node.right { right.parent = Some(node); } // Updates the size of the given node node.update_size(); } }
// Defines a private method called 'fix_after_insertion' that takes a mutable reference to a 'Node' struct and an optional mutable reference to the root node fnfix_after_insertion( mut node: &mut Node<K, V>, root: Option<&mutBox<Node<K, V>>>, ) { // Sets the color of the inserted node as 'Red' node.color = Color::Red; // Checks if the node is not the root node and its parent's color is 'Red' while node != root.unwrap() && node.parent().unwrap().color == Color::Red { letparent = node.parent().unwrap(); letgrandparent = node.grandparent().unwrap(); // Checks if the parent is the left child of its grandparent if parent == grandparent.left.as_ref().unwrap() { letuncle = grandparent.right.as_ref(); // Checks if the uncle node exists and its color is 'Red' if uncle.is_some() && uncle.unwrap().color == Color::Red { // Recolors the parent, uncle, and grandparent nodes, and sets the current node to its grandparent parent.color = Color::Black; uncle.unwrap().color = Color::Black; grandparent.color = Color::Red; node = grandparent; } else { // Checks if the current node is the right child of its parent; if so, rotates it to the left around the parent node if node == parent.right.as_ref().unwrap() { node = parent; RBTree::rotate_left(parent); } // Recolors the parent and grandparent nodes, and rotates the grandparent node to the right parent.color = Color::Black; grandparent.color = Color::Red; RBTree::rotate_right(grandparent); } } else { letuncle = grandparent.left.as_ref(); // Checks if the uncle node exists and its color is 'Red' if uncle.is_some() && uncle.unwrap().color == Color::Red { // Recolors the parent, uncle, and grandparent nodes, and sets the current node to its grandparent parent.color = Color::Black; uncle.unwrap().color = Color::Black; grandparent.color = Color::Red; node = grandparent; } else { // Checks if the current node is the left child of its parent; if so, rotates it to the right around the parent node if node == parent.left.as_ref().unwrap() { node = parent; RBTree::rotate_right(parent); } // Recolors the parent and grandparent nodes, and rotates the grandparent node to the left parent.color = Color::Black; grandparent.color = Color::Red; RBTree::rotate_left(grandparent); } } } root.unwrap().color = Color::Black; }
// Defines a public method called 'insert' that takes a key and a value and adds it to the red-black tree pubfninsert(&mutself, key: K, value: V) { // Creates a new node with the given key, value, and color 'Red' letmut new_node = Box::new(Node { key, value, color: Color::Red, left: None, right: None, });
// Checks if the root node exists ifletSome(refmut root) = self.root { letmut current = root.as_mut(); // Traverses through the tree until it finds a suitable place to insert the new node loop { if new_node.key < current.key { ifletSome(refmut left) = current.left { current = left.as_mut(); } else { current.left = Some(new_node); break; } } elseif new_node.key > current.key { ifletSome(refmut right) = current.right { current = right.as_mut(); } else { current.right = Some(new_node); break; } } else { // If the key already exists in the tree, updates its corresponding value and exits the loop current.value = new_node.value; return; } } // Fixes the tree after insertion of the new node RBTree::fix_after_insertion(current, Some(&mutself.root)); } else { // If the root node does not exist, sets the color of the new node as 'Black' and makes it the root node new_node.color = Color::Black; self.root = Some(new_node); } } }
// This function fixes the Red-Black Tree violations that may arise after a node deletion fnfix_after_deletion( mut node: &mut Node<K, V>, root: Option<&mutBox<Node<K, V>>>, ) { while node != root.unwrap() && node.color == Color::Black {
// Get the parent and sibling of the current node letparent = node.parent_mut().unwrap(); letsibling = node.sibling().unwrap();
if sibling.color == Color::Red { // Case 1: The sibling of the current node is red // Change the colors of the parent, sibling, and the child of the sibling sibling.color = Color::Black; parent.color = Color::Red; if node.is_left_child() { // Rotate left if the current node is the left child RBTree::rotate_left(parent); sibling.color = parent.right.as_ref().unwrap().color; parent.right.as_mut().unwrap().color = Color::Black; node = parent.left.as_mut().unwrap(); } else { // Rotate right if the current node is the right child RBTree::rotate_right(parent); sibling.color = parent.left.as_ref().unwrap().color; parent.left.as_mut().unwrap().color = Color::Black; node = parent.right.as_mut().unwrap(); } } else { iflet (Some(left), Some(right)) = (sibling.left.as_ref(), sibling.right.as_ref()) { if left.color == Color::Black && right.color == Color::Black { // Case 2: The sibling of the current node is black and both its children are black // Change the colors of the sibling and move up to the parent sibling.color = Color::Red; node = parent; } else { if node.is_left_child() && right.color == Color::Black { // Case 3: The sibling of the current node is black and the right child is black // Change the colors of the sibling and its left child, and rotate right sibling.color = Color::Red; left.color = Color::Black; RBTree::rotate_right(sibling); sibling = parent.right.as_mut().unwrap(); } elseif node.is_right_child() && left.color == Color::Black { // Case 3: The sibling of the current node is black and the left child is black // Change the colors of the sibling and its right child, and rotate left sibling.color = Color::Red; right.color = Color::Black; RBTree::rotate_left(sibling); sibling = parent.left.as_mut().unwrap(); }
// Case 4: The sibling of the current node is black and has a red child // Change the colors of the parent, sibling, and the child of the sibling sibling.color = parent.color; parent.color = Color::Black; if node.is_left_child() { right.color = Color::Black; RBTree::rotate_left(parent); } else { left.color = Color::Black; RBTree::rotate_right(parent); } break; } } else { // Case 2: The sibling of the current node is black and has no children ifletSome(left) = sibling.left.as_ref() { if node.is_left_child() { // Change the color of the sibling's left child and rotate right left.color = Color::Black; sibling.color = parent.color; RBTree::rotate_right(parent); } else { // Change the color of the sibling and its left child, and rotate right left.color = Color::Red; RBTree::rotate_right(sibling); sibling = parent.right.as_mut().unwrap(); } } else { if node.is_left_child() { // Change the color of the sibling and its left child, and rotate right sibling.color = Color::Red; RBTree::rotate_right(sibling); sibling = parent.right.as_mut().unwrap(); } else { // Change the colors of the parent and sibling, and rotate left sibling.color = parent.color; parent.color = Color::Black; RBTree::rotate_left(parent); break; } } } } }
// Set the color of the current node to black node.color = Color::Black; } // This function deletes a node from the Red-Black Tree according to the given key pubfndelete(&mutself, key: &K) ->Option<V> { letmut current = self.root.as_mut();
whileletSome(node) = current { if key < &node.key { current = node.left.as_mut(); } elseif key > &node.key { current = node.right.as_mut(); } else { if node.left.is_some() && node.right.is_some() { // If the node has two children, replace it with its successor and delete the successor letsuccessor = node.right.as_mut().unwrap().min_node(); node.key = successor.key; node.value = std::mem::replace(&mut successor.value, Default::default()); current = Some(&mut *successor); } else { // If the node has one child or no children, remove it and fix any Red-Black Tree violations letchild = if node.left.is_some() { node.left.take() } else { node.right.take() };
if node.color == Color::Black { ifletSome(ref c) = child { RBTree::fix_after_deletion(c.as_mut(), Some(&mutself.root)); } else { RBTree::fix_after_deletion(node, Some(&mutself.root)); } }
impl<K: Ord, V> RBTree<K, V> { pubfnsearch(&self, key: &K) ->Option<&V> { letmut current = self.root.as_ref(); // Start search from the root of the tree. whileletSome(node) = current { // Traverse the tree until the key is found or a leaf node is reached. if key == &node.key { // If the key is found, return the corresponding value. returnSome(&node.value); } elseif key < &node.key { // If the key is less than the current node's key, search the left subtree. current = node.left.as_ref(); } else { // If the key is greater than the current node's key, search the right subtree. current = node.right.as_ref(); } }