rotateRight($node); } /** * Zag rotation (single left rotation). * Performs a left rotation on the given node. * A case where the node is directly a right child of its parent. * * @param SplayTreeNode $node The node to be rotated. * @return SplayTreeNode The new root of the subtree after rotation. */ protected function zag(SplayTreeNode $node): SplayTreeNode { return $this->rotateLeft($node); } /** * Zig-Zig rotation (double right rotation). * Performs two consecutive right rotations on the given node. The first right rotation is applied to * the node’s parent, and the second one to the node’s new parent (the previous grandparent). * * @param SplayTreeNode $node The node to be rotated. * @return SplayTreeNode The new root of the subtree after the rotations. */ protected function zigZig(SplayTreeNode $node): SplayTreeNode { $node = $this->rotateRight($node); return $this->rotateRight($node); } /** * Zag-Zag rotation (double left rotation). * Performs two consecutive left rotations on the given node. The first left rotation is applied to * the node’s parent, and the second one to the node’s new parent (the previous grandparent). * * @param SplayTreeNode $node The node to be rotated. * @return SplayTreeNode The new root of the subtree after the rotations. */ protected function zagZag(SplayTreeNode $node): SplayTreeNode { $node = $this->rotateLeft($node); return $this->rotateLeft($node); } /** * Zig-Zag rotation (left-right rotation). * Performs a left rotation on the left child followed by a right rotation on the node itself. * * A case when the target key is in the right subtree of the left child. * * @param SplayTreeNode $node The node to be rotated. * @return SplayTreeNode The new root of the subtree after the rotations. */ protected function zigZag(SplayTreeNode $node): SplayTreeNode { $node->left = $this->rotateLeft($node->left); return $this->rotateRight($node); } /** * Zag-Zig rotation (right-left rotation). * Performs a right rotation on the right child followed by a left rotation on the node itself. * * A case when the target key is in the left subtree of the right child. * * @param SplayTreeNode $node The node to be rotated. * @return SplayTreeNode The new root of the subtree after the rotations. */ protected function zagZig(SplayTreeNode $node): SplayTreeNode { $node->right = $this->rotateRight($node->right); return $this->rotateLeft($node); } /** * Rotates the given node to the left, bringing its right child up to take its place. * The left subtree of the node's right child will become the new right subtree of the node. * * @param SplayTreeNode $node The node to be rotated. * @return SplayTreeNode The new root of the subtree after the rotation (the former right child). */ private function rotateLeft(SplayTreeNode $node): SplayTreeNode { $rightChild = $node->right; if ($rightChild === null) { return $node; // No rotation possible } $node->right = $rightChild->left; if ($rightChild->left !== null) { $rightChild->left->parent = $node; } $rightChild->parent = $node->parent; if ($node->parent === null) { static::setRoot($rightChild); } elseif ($node === $node->parent->left) { $node->parent->left = $rightChild; } else { $node->parent->right = $rightChild; } $rightChild->left = $node; $node->parent = $rightChild; return $rightChild; } /** * Rotates the given node to the right, bringing its left child up to take its place. * The right subtree of the node's left child will become the new left subtree of the node. * * @param SplayTreeNode $node The node to be rotated. * @return SplayTreeNode The new root of the subtree after the rotation (the former left child). */ private function rotateRight(SplayTreeNode $node): SplayTreeNode { $leftChild = $node->left; if ($leftChild === null) { return $node; // No rotation possible } $node->left = $leftChild->right; if ($leftChild->right !== null) { $leftChild->right->parent = $node; } $leftChild->parent = $node->parent; if ($node->parent === null) { static::setRoot($leftChild); } elseif ($node === $node->parent->right) { $node->parent->right = $leftChild; } else { $node->parent->left = $leftChild; } $leftChild->right = $node; $node->parent = $leftChild; return $leftChild; } }