Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 797a6f2

Browse files
committed
Make it possible to use objects as a values for binary search tree nodes.
1 parent 3ae9c40 commit 797a6f2

File tree

3 files changed

+82
-7
lines changed

3 files changed

+82
-7
lines changed

‎src/data-structures/tree/binary-search-tree/BinarySearchTree.js‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,31 @@ export default class BinarySearchTree {
55
this.root = new BinarySearchTreeNode();
66
}
77

8+
/**
9+
* @param {*} value
10+
*/
811
insert(value) {
912
this.root.insert(value);
1013
}
1114

15+
/**
16+
* @param {*} value
17+
* @return {boolean}
18+
*/
1219
contains(value) {
1320
return this.root.contains(value);
1421
}
1522

23+
/**
24+
* @param {*} value
25+
*/
1626
remove(value) {
1727
return this.root.remove(value);
1828
}
1929

30+
/**
31+
* @return {string}
32+
*/
2033
toString() {
2134
return this.root.toString();
2235
}

‎src/data-structures/tree/binary-search-tree/BinarySearchTreeNode.js‎

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,37 @@
11
import BinaryTreeNode from '../BinaryTreeNode';
2+
import Comparator from '../../../utils/comparator/Comparator';
23

34
export default class BinarySearchTreeNode extends BinaryTreeNode {
5+
/**
6+
* @param {*} value
7+
* @param {BinaryTreeNode} parent
8+
* @param {function} compareFunction
9+
*/
10+
constructor(value = null, parent = null, compareFunction = undefined) {
11+
super(value, parent);
12+
13+
// This comparator is used to compare node values with each other.
14+
this.nodeValueComparator = new Comparator(compareFunction);
15+
}
16+
17+
/**
18+
* @param {*} value
19+
* @return {BinarySearchTreeNode}
20+
*/
421
insert(value) {
5-
if (this.value===null) {
22+
if (this.nodeValueComparator.equal(this.value,null)) {
623
this.value = value;
724
return this;
825
}
926

10-
if (value<this.value) {
27+
if (this.nodeValueComparator.lessThan(value,this.value)) {
1128
// Insert to the left.
1229
if (this.left) {
1330
this.left.insert(value);
1431
} else {
1532
this.setLeft(new BinarySearchTreeNode(value));
1633
}
17-
} else if (value>this.value) {
34+
} else if (this.nodeValueComparator.greaterThan(value,this.value)) {
1835
// Insert to the right.
1936
if (this.right) {
2037
this.right.insert(value);
@@ -26,27 +43,38 @@ export default class BinarySearchTreeNode extends BinaryTreeNode {
2643
return this;
2744
}
2845

46+
/**
47+
* @param {*} value
48+
* @return {BinarySearchTreeNode}
49+
*/
2950
find(value) {
3051
// Check the root.
31-
if (this.value===value) {
52+
if (this.nodeValueComparator.equal(this.value,value)) {
3253
return this;
3354
}
3455

35-
if (value<this.value && this.left) {
56+
if (this.nodeValueComparator.lessThan(value,this.value) && this.left) {
3657
// Check left nodes.
3758
return this.left.find(value);
38-
} else if (value>this.value && this.right) {
59+
} else if (this.nodeValueComparator.greaterThan(value,this.value) && this.right) {
3960
// Check right nodes.
4061
return this.right.find(value);
4162
}
4263

4364
return null;
4465
}
4566

67+
/**
68+
* @param {*} value
69+
* @return {boolean}
70+
*/
4671
contains(value) {
4772
return !!this.find(value);
4873
}
4974

75+
/**
76+
* @param {*} value
77+
*/
5078
remove(value) {
5179
const nodeToRemove = this.find(value);
5280

@@ -65,7 +93,7 @@ export default class BinarySearchTreeNode extends BinaryTreeNode {
6593
// Find the next biggest value (minimum value in the right branch)
6694
// and replace current value node with that next biggest value.
6795
const nextBiggerNode = nodeToRemove.right.findMin();
68-
if (nextBiggerNode!==nodeToRemove.right) {
96+
if (!this.nodeComparator.equal(nextBiggerNode,nodeToRemove.right)) {
6997
this.remove(nextBiggerNode.value);
7098
nodeToRemove.value = nextBiggerNode.value;
7199
} else {
@@ -85,6 +113,9 @@ export default class BinarySearchTreeNode extends BinaryTreeNode {
85113
}
86114
}
87115

116+
/**
117+
* @return {BinarySearchTreeNode}
118+
*/
88119
findMin() {
89120
if (!this.left) {
90121
return this;

‎src/data-structures/tree/binary-search-tree/__test__/BinarySearchTreeNode.test.js‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,35 @@ describe('BinarySearchTreeNode', () => {
171171

172172
expect(removeNotExistingElementFromTree).toThrow();
173173
});
174+
175+
it('should be possible to use objects as node values', () => {
176+
const nodeValueComparatorCallback = (a, b) => {
177+
const normalizedA = a || { value: null };
178+
const normalizedB = b || { value: null };
179+
180+
if (normalizedA.value === normalizedB.value) {
181+
return 0;
182+
}
183+
184+
return normalizedA.value < normalizedB.value ? -1 : 1;
185+
};
186+
187+
const obj1 = { key: 'obj1', value: 1, toString: () => 'obj1' };
188+
const obj2 = { key: 'obj2', value: 2, toString: () => 'obj2' };
189+
const obj3 = { key: 'obj3', value: 3, toString: () => 'obj3' };
190+
191+
const bstNode = new BinarySearchTreeNode(obj2, null, nodeValueComparatorCallback);
192+
bstNode.insert(obj1);
193+
194+
expect(bstNode.toString()).toBe('obj1,obj2');
195+
expect(bstNode.contains(obj1)).toBeTruthy();
196+
expect(bstNode.contains(obj3)).toBeFalsy();
197+
198+
bstNode.insert(obj3);
199+
200+
expect(bstNode.toString()).toBe('obj1,obj2,obj3');
201+
expect(bstNode.contains(obj3)).toBeTruthy();
202+
203+
expect(bstNode.findMin().value).toEqual(obj1);
204+
});
174205
});

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /