Skip to content

feat: add callback functionality for binary search tree #6730

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

dquixote-jr
Copy link

I need the functionality to find the k'th node in the tree, which isn't possible with current setup
This augmentation allows people to define whatever functions that they want, in this particular case, it allows me to store the subtree size in a parameter st_size and which I can use to find the k'th node in order.

First javascript project PR so this is gonna have some issues, happy to solve them.

@dquixote-jr dquixote-jr requested a review from kt3k as a code owner June 20, 2025 22:37
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@@ -8,4 +8,5 @@ export class MyMath {
export interface Container {
id: number;
values: number[];
st_size: number;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use camelCase?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@@ -104,12 +105,18 @@ export class BinarySearchTree<T> implements Iterable<T> {
* @param compare A custom comparison function to sort the values in the tree.
* By default, the values are sorted in ascending order.
*/
constructor(compare: (a: T, b: T) => number = ascend) {
constructor(compare: (a: T, b: T) => number = ascend, callback?: (node: BinarySearchNode<T>) => void) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to document callback param in jsdoc.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the param.

@kt3k
Copy link
Member

kt3k commented Jun 23, 2025

I need the functionality to find the k'th node in the tree, which isn't possible with current setup

This change doesn't seem a good idea for adding that capability to this class. Currently BinarySearchNode class is private. This makes it a part of public API. That doesn't seem an ideal change. Can we achieve this without exposing node class public?

For small k's, it seems we can use lnrValues (or rnlValues) iterator for finding k'th node. What do your tree size and k value typically look like?

@dquixote-jr
Copy link
Author

For small k's, it seems we can use lnrValues (or rnlValues) iterator for finding k'th node. What do your tree size and k value typically look like?

The tree can be large, like ~5K. And k can be as large as O(n), so iterating over values with lnr/rnl isn't really a good idea.

This change doesn't seem a good idea for adding that capability to this class. Currently BinarySearchNode class is private.

I don't think it's the worst thing to make the BinarySearchNode a public class, as we have already made it a "binary" tree, so having left/right/parent elements is expected of it. A different thing to do would be to expose the BinarySearchNode class, but not give access directly to member objects but rather have setChild/getChild or set/get Left/Right/Parent kind of functions.
I'm open to any other ideas too, my main use case is to allow people to travel over the tree via nodes somehow via left/right nodes. I don't need them to be able to access the specific internal attributes of the class, just left/right children.

Copy link

codecov bot commented Jun 23, 2025

Codecov Report

Attention: Patch coverage is 91.66667% with 6 lines in your changes missing coverage. Please review.

Project coverage is 93.70%. Comparing base (2258bf2) to head (a2fd74c).

Files with missing lines Patch % Lines
data_structures/binary_search_tree.ts 91.17% 2 Missing and 1 partial ⚠️
data_structures/red_black_tree.ts 66.66% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6730      +/-   ##
==========================================
- Coverage   94.65%   93.70%   -0.95%     
==========================================
  Files         576      559      -17     
  Lines       47065    46838     -227     
  Branches     6610     6472     -138     
==========================================
- Hits        44549    43890     -659     
- Misses       2473     2902     +429     
- Partials       43       46       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kt3k
Copy link
Member

kt3k commented Jun 23, 2025

I don't think it's the worst thing to make the BinarySearchNode a public class, as we have already made it a "binary" tree, so having left/right/parent elements is expected of it. A different thing to do would be to expose the BinarySearchNode class, but not give access directly to member objects but rather have setChild/getChild or set/get Left/Right/Parent kind of functions.

Then maybe it's better to define a new interface which only has left, right, and parent (and maybe value) fields, and use it as input type for callback?

Also run deno task lint and see the output. We need to fix them to merge this to main

@dquixote-jr
Copy link
Author

Then maybe it's better to define a new interface which only has left, right, and parent (and maybe value) fields, and use it as input type for callback?

That sounds like a good idea. I've added a new class BSTNode and refactored the setup to use that.

Also run deno task lint and see the output. We need to fix them to merge this to main

Thank you for this. I've got it passing locally. import type gave me a headspin but I got it working in the end :)

Copy link
Member

@kt3k kt3k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now looks much better to me. Left some comments

*
* @typeparam T The type of the values stored in the binary tree.
*/
export class BSTNode<T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually avoid using this type of acronym in API names. BinarySearchTree used to be BSTree but we renamed it later #2400 I think this should be named BinarySearchTreeNode.

Also I think this should be typescript interface instead of class. We can avoid unnecessary runtime overhead by making this interface

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, renamed to BinarySearchTreeNode and made into an interface.

// This module is browser compatible.

/**
* A generic Binary Search Tree (BST) node class.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely documented 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants