fix(data-structures): deep-copy nodes in BinarySearchTree/RedBlackTree.from()#7230
Open
LeSingh1 wants to merge 1 commit into
Open
fix(data-structures): deep-copy nodes in BinarySearchTree/RedBlackTree.from()#7230LeSingh1 wants to merge 1 commit into
LeSingh1 wants to merge 1 commit into
Conversation
…e.from() When copying an existing tree, from() created a copy of only the root node and then, while walking the tree, built copies of each child but never re-linked the parent copy's left/right pointers to those copies. As a result the returned tree still referenced the original tree's descendant nodes, so mutating the copy (e.g. remove()) corrupted the original. RedBlackTree.from() was additionally seeding the result with the original root node itself rather than a copy. Re-link node.left/node.right to the freshly created child copies during the traversal, and copy the root node in RedBlackTree.from() before using it. Add regression tests asserting that removals in either the copy or the original do not affect the other. Fixes denoland#6314 Fixes denoland#6315
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
BinarySearchTree.from()andRedBlackTree.from()are documented to create anindependent copy of an existing tree, but they only performed a partial copy.
The traversal that walks the source tree created a copy of each child node and
fixed up the child's
parentpointer, but it never re-linked the parent copy'sleft/rightpointers to point at those new child copies. BecauseBinarySearchNode.from()/RedBlackNode.from()seed a copy'sleft/rightwith the original node's children, the returned tree ended up still
referencing the source tree's descendant nodes.
RedBlackTree.from()was additionally worse: it seeded the result with thesource tree's root node itself (via
setRoot(result, root)) rather than acopy of it.
The net effect is that the "copy" shares nodes with the original, so mutating
the copy corrupts the original (and vice versa):
Fixes #6314
Fixes #6315
Fix
node.left/node.rightto the freshly created child copies duringthe copy traversal in both
BinarySearchTree.from()andRedBlackTree.from().RedBlackTree.from(), copy the root node before seeding the result with it(so the traversal no longer mutates the source root).
The mapped / custom-comparator paths are unchanged (they already rebuild the
tree via
insert()).Verification
copy or the original leaves the other intact. They fail on
main(
original.find(7)returnsnull) and pass with this change.deno test data_structures/→ 350 passed, 0 failed.deno fmt --checkanddeno linton the changed files are clean.deno checkon the changed files passes.