From 3ae9c404165da17d3f51093579637a08eb335457 Mon Sep 17 00:00:00 2001 From: Oleksii Trekhleb Date: Wed, 30 May 2018 07:19:48 +0300 Subject: [PATCH] Test that it is possible to use objects and binary tree node values. --- src/data-structures/tree/BinaryTreeNode.js | 52 +++++++++++++++++-- .../tree/__test__/BinaryTreeNode.test.js | 23 ++++++++ 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/data-structures/tree/BinaryTreeNode.js b/src/data-structures/tree/BinaryTreeNode.js index 1c3d2608..847626a3 100644 --- a/src/data-structures/tree/BinaryTreeNode.js +++ b/src/data-structures/tree/BinaryTreeNode.js @@ -1,11 +1,23 @@ +import Comparator from '../../utils/comparator/Comparator'; + export default class BinaryTreeNode { + /** + * @param {*} value + * @param {BinaryTreeNode} parent + */ constructor(value = null, parent = null) { this.left = null; this.right = null; this.parent = parent; this.value = value; + + // This comparator is used to compare binary tree nodes with each other. + this.nodeComparator = new Comparator(); } + /** + * @return {number} + */ get leftHeight() { if (!this.left) { return 0; @@ -14,6 +26,9 @@ export default class BinaryTreeNode { return this.left.height + 1; } + /** + * @return {number} + */ get rightHeight() { if (!this.right) { return 0; @@ -22,14 +37,24 @@ export default class BinaryTreeNode { return this.right.height + 1; } + /** + * @return {number} + */ get height() { return Math.max(this.leftHeight, this.rightHeight); } + /** + * @return {number} + */ get balanceFactor() { return this.leftHeight - this.rightHeight; } + /** + * @param {BinaryTreeNode} node + * @return {BinaryTreeNode} + */ setLeft(node) { // Reset parent for left node since it is going to be detached. if (this.left) { @@ -47,6 +72,10 @@ export default class BinaryTreeNode { return this; } + /** + * @param {BinaryTreeNode} node + * @return {BinaryTreeNode} + */ setRight(node) { // Reset parent for right node since it is going to be detached. if (this.right) { @@ -64,13 +93,17 @@ export default class BinaryTreeNode { return this; } + /** + * @param {BinaryTreeNode} nodeToRemove + * @return {boolean} + */ removeChild(nodeToRemove) { - if (this.left && this.left === nodeToRemove) { + if (this.left && this.nodeComparator.equal(this.left, nodeToRemove)) { this.left = null; return true; } - if (this.right && this.right === nodeToRemove) { + if (this.right && this.nodeComparator.equal(this.right, nodeToRemove)) { this.right = null; return true; } @@ -78,17 +111,22 @@ export default class BinaryTreeNode { return false; } + /** + * @param {BinaryTreeNode} nodeToReplace + * @param {BinaryTreeNode} replacementNode + * @return {boolean} + */ replaceChild(nodeToReplace, replacementNode) { if (!nodeToReplace || !replacementNode) { return false; } - if (this.left && this.left === nodeToReplace) { + if (this.left && this.nodeComparator.equal(this.left, nodeToReplace)) { this.left = replacementNode; return true; } - if (this.right && this.right === nodeToReplace) { + if (this.right && this.nodeComparator.equal(this.right, nodeToReplace)) { this.right = replacementNode; return true; } @@ -96,6 +134,9 @@ export default class BinaryTreeNode { return false; } + /** + * @return {*[]} + */ traverseInOrder() { let traverse = []; @@ -115,6 +156,9 @@ export default class BinaryTreeNode { return traverse; } + /** + * @return {string} + */ toString() { return this.traverseInOrder().toString(); } diff --git a/src/data-structures/tree/__test__/BinaryTreeNode.test.js b/src/data-structures/tree/__test__/BinaryTreeNode.test.js index 9160a965..8474798f 100644 --- a/src/data-structures/tree/__test__/BinaryTreeNode.test.js +++ b/src/data-structures/tree/__test__/BinaryTreeNode.test.js @@ -173,4 +173,27 @@ describe('BinaryTreeNode', () => { expect(root.left).toBeNull(); expect(root.right).toBeNull(); }); + + it('should be possible to create node with object as a value', () => { + const obj1 = { key: 'object_1', toString: () => 'object_1' }; + const obj2 = { key: 'object_2' }; + + const node1 = new BinaryTreeNode(obj1); + const node2 = new BinaryTreeNode(obj2); + + node1.setLeft(node2); + + expect(node1.value).toEqual(obj1); + expect(node2.value).toEqual(obj2); + expect(node1.left.value).toEqual(obj2); + + node1.removeChild(node2); + + expect(node1.value).toEqual(obj1); + expect(node2.value).toEqual(obj2); + expect(node1.left).toBeNull(); + + expect(node1.toString()).toBe('object_1'); + expect(node2.toString()).toBe('[object Object]'); + }); });