-
Notifications
You must be signed in to change notification settings - Fork 314
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
feat: AVL Implementation of BinarySearchTree #67
Conversation
…breakpoints on your code and Ctrl+F5 away to debug :)Hints: 'test.skip' and 'test.only' are useful to run only selected tests
the AvtTree is inherited from BinarySearchTree. However duplicates are not properly handled yet in Avl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot Hieu!
@@ -5,39 +5,9 @@ class BinarySearchTree extends BinaryTree<number> { | |||
/** | |||
* Recursively insert a new value in the BST. | |||
* @param {number} value The value being inserted | |||
* @param {BinaryTreeNode} node The current node. Param is not required. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for catching this
I think I'll leave out the case of handling duplicates. Do you have any recommendations on how this is done usually? |
No particular preferences actually, I tend to follow the patterns employed in the framework/project: For example, Java/C# libraries heavily relied on template method pattern (they use Comparer/Comparator) to alter the behaviour of the algorithm. So if I were to work on these languages, I probably modify the Comparer to handle tiebreak. As long as your comparator is deterministic you are ok: // Assume GetObjectId returns an unique id. In C/C++ maybe you can rely on pointer memory address.
const tiebreakComparer = (a,b) => comparer(a,b) || a.GetObjectId().CompareTo(b.GetObjectId()) Having a comparer makes your data struct really versatile 😄 However, the proper AVL tree implementation would normally handle duplicates by keeping an extra integer in the node for duplication count. i.e: class AvlTreeNode extends BinaryTreeNode {
constructor AvlTreeNode(value) {
super(value);
this.duplicate = 1;
}
} For insert/delete, when binarySearch the exact item, just +1 on |
Personally for this project, I think it is best to include the comparer for BinarySearchTree for two reasons:
Something like this: class BinarySearchTree {
constructor(comparer) {
this.root = null;
this.comparer = comparer || ((a, b) => a - b);
}
...
} I have the whole class already implemented in Js. Would you like me to make the same modification for Ts? |
Description:
Written a simple AVL Tree extending BinarySearchTree. Expose BST
insertImpl
anddeleteImpl
for a more elegant AVL extension :)Essentially:
Type of change:
New feature (non-breaking change which adds functionality)
How Has This Been Tested?
Tested against the test cases for BST.
Added extra test cases for AVL rotations to check for correctness.
Current problem:
This AVL implementations should work flawlessly for tree with unique elements, but would not ensure correctness when we have duplicate elements (due to rotations, check the skipped tests).
I kinda think of 3 ways to deal with it:
Your choice on how you want to deal with this :)
Related Issues
#5