diff --git a/CHANGELOG.md b/CHANGELOG.md index 5139f383..23e12bd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Bug Fixes (patch) +## [1.3.7] + +### Breaking Changes (major) + +### New Features (minor) + +### Bug Fixes (patch) +- fix(avl-tree): balance was not working properly [commit](https://github.com/amejiarosario/dsa.js/commit/98e2c037f05caf37731da1dc50dd8867a1804c0e) + ## [1.3.6] ### Breaking Changes (major) @@ -21,7 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Bug Fixes (patch) - update deps [commit](https://github.com/amejiarosario/dsa.js/commit/d8ce2f5b1a3bfeb861928d6c99d7624cd9ac144a) -- style: fix eslint issue [commit](https://github.com/amejiarosario/dsa.js/commit/72e3d68e09bb9c7dd3fabf5cbeba1ae5571fc686)% +- style: fix eslint issue [commit](https://github.com/amejiarosario/dsa.js/commit/72e3d68e09bb9c7dd3fabf5cbeba1ae5571fc686) ## [1.3.5] @@ -116,7 +125,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - -[Unreleased]: https://github.com/amejiarosario/dsa.js/compare/1.3.6...HEAD +[Unreleased]: https://github.com/amejiarosario/dsa.js/compare/1.3.7...HEAD +[1.3.6]: https://github.com/amejiarosario/dsa.js/compare/1.3.6...1.3.7 [1.3.6]: https://github.com/amejiarosario/dsa.js/compare/1.3.5...1.3.6 [1.3.5]: https://github.com/amejiarosario/dsa.js/compare/1.3.4...1.3.5 [1.3.4]: https://github.com/amejiarosario/dsa.js/compare/1.2.3...1.3.4 diff --git a/notes.md b/notes.md index 4cc5c330..2f927d2b 100644 --- a/notes.md +++ b/notes.md @@ -22,9 +22,9 @@ git log HEAD --pretty=format:%s # example git log 1.1.0..HEAD --pretty=format:%s -git log 1.3.4..HEAD --pretty=format:"- %s [commit](https://github.com/amejiarosario/dsa.js/commit/%H)" --grep "BREAKING CHANGE:" -git log 1.3.4..HEAD --pretty=format:"- %s [commit](https://github.com/amejiarosario/dsa.js/commit/%H)" --grep "^feat.*:" -git log 1.3.4..HEAD --pretty=format:"- %s [commit](https://github.com/amejiarosario/dsa.js/commit/%H)" --grep "^fix.*:" +git log 1.3.6..HEAD --pretty=format:"- %s [commit](https://github.com/amejiarosario/dsa.js/commit/%H)" --grep "BREAKING CHANGE:" +git log 1.3.6..HEAD --pretty=format:"- %s [commit](https://github.com/amejiarosario/dsa.js/commit/%H)" --grep "^feat.*:" +git log 1.3.6..HEAD --pretty=format:"- %s [commit](https://github.com/amejiarosario/dsa.js/commit/%H)" --grep "^fix.*:" ``` New features in this release diff --git a/package.json b/package.json index 4d6382da..ad911a4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dsa.js", - "version": "1.3.6", + "version": "1.3.7", "description": "Data Structures & Algorithms in JS", "author": "Adrian Mejia (https://adrianmejia.com)", "homepage": "https://github.com/amejiarosario/dsa.js", diff --git a/src/data-structures/trees/avl-tree.js b/src/data-structures/trees/avl-tree.js index 573095bd..272a16e1 100644 --- a/src/data-structures/trees/avl-tree.js +++ b/src/data-structures/trees/avl-tree.js @@ -17,23 +17,21 @@ const { * - LR rotations: double rotation left-right * - RL rotations: double rotation right-left * - * @param {TreeNode} node + * @param {BinaryTreeNode} node */ function balance(node) { if (node.balanceFactor > 1) { // left subtree is higher than right subtree - if (node.left.balanceFactor > 0) { - return rightRotation(node); - } if (node.left.balanceFactor < 0) { + if (node.left.balanceFactor < 0) { return leftRightRotation(node); } - } else if (node.balanceFactor < -1) { + return rightRotation(node); + } if (node.balanceFactor < -1) { // right subtree is higher than left subtree - if (node.right.balanceFactor < 0) { - return leftRotation(node); - } if (node.right.balanceFactor > 0) { + if (node.right.balanceFactor > 0) { return rightLeftRotation(node); } + return leftRotation(node); } return node; } @@ -43,7 +41,7 @@ function balance(node) { /** * Bubbles up balancing nodes a their parents * - * @param {TreeNode} node + * @param {BinaryTreeNode} node */ function balanceUpstream(node) { let current = node; diff --git a/src/data-structures/trees/avl-tree.spec.js b/src/data-structures/trees/avl-tree.spec.js index a0c79d34..af831cdc 100644 --- a/src/data-structures/trees/avl-tree.spec.js +++ b/src/data-structures/trees/avl-tree.spec.js @@ -165,4 +165,65 @@ describe('AvlTree', () => { null, null, null, null, null, null]); }); }); + + describe('balancing to the left', () => { + let n32; + beforeEach(() => { + n32 = tree.add(32); + tree.add(8); + tree.add(64); + tree.add(4); + tree.add(16); + tree.add(48); + tree.add(128); + tree.add(2); + tree.add(6); + tree.add(10); + tree.add(20); + }); + + it('should have all nodes', () => { + expect(tree.toArray()).toEqual([32, 8, 64, 4, 16, 48, 128, 2, 6, 10, 20, + null, null, null, null, null, null, null, null, null, null, null, null]); + }); + + it('should rebalance when removing', () => { + tree.remove(64); + expect(tree.toArray()).toEqual([32, 8, 128, 4, 16, 48, null, 2, 6, 10, 20, + null, null, null, null, null, null, null, null, null, null]); + expect(n32.balanceFactor).toBe(1); + expect(n32.right.balanceFactor).toBe(1); + expect(n32.left.balanceFactor).toBe(0); + + tree.remove(48); + expect(tree.toArray()).toEqual([8, 4, 32, 2, 6, 16, 128, null, null, null, null, 10, 20, + null, null, null, null, null, null]); + }); + }); + + describe('balancing to the right', () => { + beforeEach(() => { + tree.add(8); + tree.add(4); + tree.add(32); + tree.add(2); + tree.add(16); + tree.add(64); + tree.add(10); + tree.add(20); + tree.add(60); + tree.add(70); + }); + + it('should build the tree', () => { + expect(tree.toArray()).toEqual([8, 4, 32, 2, null, 16, 64, null, null, 10, 20, 60, 70, + null, null, null, null, null, null, null, null]); + }); + + it('should rebalance right side', () => { + tree.remove(2); + expect(tree.toArray()).toEqual([32, 8, 64, 4, 16, 60, 70, null, null, 10, 20, + null, null, null, null, null, null, null, null]); + }); + }); });