Removes the given node, and returns the node that was physically removed from the tree.
(
node: BinarySearchNode<T>,
)
| 385 | |
| 386 | /** Removes the given node, and returns the node that was physically removed from the tree. */ |
| 387 | #removeNode( |
| 388 | node: BinarySearchNode<T>, |
| 389 | ): BinarySearchNode<T> | null { |
| 390 | /** |
| 391 | * The node to physically remove from the tree. |
| 392 | * Guaranteed to have at most one child. |
| 393 | */ |
| 394 | const flaggedNode: BinarySearchNode<T> | null = !node.left || !node.right |
| 395 | ? node |
| 396 | : node.findSuccessorNode()!; |
| 397 | /** Replaces the flagged node. */ |
| 398 | const replacementNode: BinarySearchNode<T> | null = flaggedNode.left ?? |
| 399 | flaggedNode.right; |
| 400 | |
| 401 | if (replacementNode) replacementNode.parent = flaggedNode.parent; |
| 402 | if (!flaggedNode.parent) { |
| 403 | this.#root = replacementNode; |
| 404 | } else { |
| 405 | flaggedNode.parent[flaggedNode.directionFromParent()!] = replacementNode; |
| 406 | } |
| 407 | if (flaggedNode !== node) { |
| 408 | /** Swaps values, in case value of the removed node is still needed by consumer. */ |
| 409 | const swapValue = node.value; |
| 410 | node.value = flaggedNode.value; |
| 411 | flaggedNode.value = swapValue; |
| 412 | } |
| 413 | |
| 414 | this.#size--; |
| 415 | return flaggedNode; |
| 416 | } |
| 417 | |
| 418 | /** |
| 419 | * Add a value to the binary search tree if it does not already exist in the |
no test coverage detected