import { Direction, RedBlackNode, } from "https://deno.land/std@0.188.0/collections/red_black_node.ts"; import { RedBlackTree } from "https://deno.land/std@0.188.0/collections/red_black_tree.ts"; export default class RedBlackTreeExtended extends RedBlackTree { insertGetNode(value: T): RedBlackNode | null { let node = this.insertNode( RedBlackNode, value, ) as RedBlackNode | null; if (node) { while (node.parent?.red) { let parent: RedBlackNode = node.parent!; const parentDirection: Direction = parent .directionFromParent()!; const uncleDirection: Direction = parentDirection === "right" ? "left" : "right"; const uncle: RedBlackNode | null = parent.parent![uncleDirection] ?? null; if (uncle?.red) { parent.red = false; uncle.red = false; parent.parent!.red = true; node = parent.parent!; } else { if (node === parent[uncleDirection]) { node = parent; this.rotateNode(node, parentDirection); parent = node.parent!; } parent.red = false; parent.parent!.red = true; this.rotateNode(parent.parent!, uncleDirection); } } this.root!.red = false; } return node; } getRoot(): RedBlackNode | null { return this.root; } removeTreeNode(removeNode: RedBlackNode) { const successorNode: RedBlackNode | null = ( !removeNode.left || !removeNode.right ? removeNode : removeNode.findSuccessorNode()! ) as RedBlackNode; const replacementNode: RedBlackNode | null = successorNode.left ?? successorNode.right; if (replacementNode) replacementNode.parent = successorNode.parent; if (!successorNode.parent) { this.root = replacementNode; } else { successorNode.parent[successorNode.directionFromParent()!] = replacementNode; } if (successorNode !== removeNode) { removeNode.value = successorNode.value; removeNode = successorNode; } this._size--; const node = removeNode; if (node && !node.red) { this.removeFixup(node.parent, node.left ?? node.right); } return; } }