Skip to content

Commit 29f1b16

Browse files
committed
refactor: moved the core logic to Utils for a clean BST class
1 parent 944f4c6 commit 29f1b16

File tree

2 files changed

+144
-135
lines changed

2 files changed

+144
-135
lines changed

src/_DataStructures_/Trees/BinarySearchTree/index.js

+12-135
Original file line numberDiff line numberDiff line change
@@ -1,175 +1,52 @@
11
/* eslint-disable consistent-return */
22
const Node = require('./Node');
3+
const BSTUtils = require('./utils');
34

45
class BinarySearchTree {
56
constructor(value) {
67
if (!value) throw new Error('Root node value required');
78
this.root = new Node(value);
8-
}
9-
10-
insert(root, value) {
11-
if (root === null) {
12-
const newNode = new Node(value);
13-
// eslint-disable-next-line no-param-reassign
14-
root = newNode;
15-
return root;
16-
}
17-
18-
if (value < root.value) {
19-
// eslint-disable-next-line no-param-reassign
20-
root.leftChild = this.insert(root.leftChild, value);
21-
return root;
22-
}
23-
if (value > root.value) {
24-
// eslint-disable-next-line no-param-reassign
25-
root.rightChild = this.insert(root.rightChild, value);
26-
return root;
27-
}
28-
}
29-
30-
preorder(root) {
31-
/** returning an array so as to make testing easy */
32-
let arr = [];
33-
if (root === null) return [];
34-
arr.push(root.value);
35-
36-
const left = this.preorder(root.leftChild);
37-
arr = [...arr, ...left];
38-
39-
const right = this.preorder(root.rightChild);
40-
arr = [...arr, ...right];
41-
return arr;
42-
}
43-
44-
inorder(root) {
45-
/** left - root - right */
46-
if (root === null) return [];
47-
let arr = [];
48-
const left = this.inorder(root.leftChild);
49-
arr = [...left, ...arr];
50-
51-
// print root
52-
arr = [...arr, root.value];
53-
54-
const right = this.inorder(root.rightChild);
55-
arr = [...arr, ...right];
56-
return arr;
57-
}
58-
59-
postorder(root) {
60-
/** left - right - root */
61-
62-
if (root === null) return [];
63-
let arr = [];
64-
65-
const left = this.postorder(root.leftChild);
66-
arr = [...left, ...arr];
67-
68-
const right = this.postorder(root.rightChild);
69-
arr = [...arr, ...right];
70-
71-
return [...arr, root.value];
72-
}
73-
74-
search(root, value) {
75-
if (root === null) return false;
76-
if (value === root.value) return true;
77-
78-
if (value < root.value) {
79-
return this.search(root.leftChild, value);
80-
}
81-
if (value > root.value) {
82-
return this.search(root.rightChild, value);
83-
}
84-
}
85-
86-
delete(root, value) {
87-
if (root === null) {
88-
return root;
89-
}
90-
91-
if (value > root.value) {
92-
// eslint-disable-next-line no-param-reassign
93-
root.rightChild = this.delete(root.rightChild, value);
94-
} else if (value < root.value) {
95-
// eslint-disable-next-line no-param-reassign
96-
root.leftChild = this.delete(root.leftChild, value);
97-
} else {
98-
// found the node
99-
if (root.leftChild === null) {
100-
// there is a right sub-tree
101-
return root.rightChild;
102-
}
103-
if (root.rightChild === null) {
104-
// there is a left sub-tree
105-
return root.leftChild;
106-
}
107-
/**
108-
* the root contain 2 childs, we got 2 options:
109-
* 1. We can either find the Node with minimum value at from the right sub-tree
110-
* 2. Or, we can find the Node with maximum value from the left sub-tree
111-
*
112-
* I'm picking up 1 here
113-
*/
114-
const minRightNode = this.findMinNode(root.rightChild);
115-
// eslint-disable-next-line no-param-reassign
116-
root.value = minRightNode.value;
117-
// eslint-disable-next-line no-param-reassign
118-
root.rightChild = this.delete(root.rightChild, minRightNode.value);
119-
return root;
120-
}
121-
return root;
122-
}
123-
124-
findMinNode(root) {
125-
/** The minnimum values is the let most leaf node in BST */
126-
if (root.leftChild === null) return root;
127-
return this.findMinNode(root.leftChild);
128-
}
129-
130-
findMaxNode(root) {
131-
if (root.rightChild === null) return root;
132-
return this.findMaxNode(root.rightChild);
9+
this.BSTUtils = BSTUtils;
13310
}
13411

13512
isEmpty() {
13613
return this.root === null;
13714
}
13815

139-
/** Layered methods to simplify the BST API */
16+
/** Layered methods to simplify the BST API using utils under the hood */
14017

14118
add(value) {
142-
return this.insert(this.root, value);
19+
return this.BSTUtils.insert(this.root, value);
14320
}
14421

145-
traversePreorder() {
146-
return this.preorder(this.root);
22+
preorder() {
23+
return this.BSTUtils.preorder(this.root);
14724
}
14825

14926
traversePostorder() {
150-
return this.postorder(this.root);
27+
return this.BSTUtils.postorder(this.root);
15128
}
15229

15330
traverseInorder() {
154-
return this.inorder(this.root);
31+
return this.BSTUtils.inorder(this.root);
15532
}
15633

15734
searchFor(value) {
158-
return this.search(this.root, value);
35+
return this.BSTUtils.search(this.root, value);
15936
}
16037

16138
getMinimum() {
162-
const minNode = this.findMinNode(this.root);
39+
const minNode = this.BSTUtils.findMinNode(this.root);
16340
return minNode.value;
16441
}
16542

16643
getMaximum() {
167-
const maxNode = this.findMaxNode(this.root);
44+
const maxNode = this.BSTUtils.findMaxNode(this.root);
16845
return maxNode.value;
16946
}
17047

17148
remove(value) {
172-
this.root = this.delete(this.root, value);
49+
this.root = this.BSTUtils.delete(this.root, value);
17350
}
17451
}
17552

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
const Node = require('./Node');
2+
3+
const utils = {
4+
// eslint-disable-next-line consistent-return
5+
insert(root, value) {
6+
if (root === null) {
7+
const newNode = new Node(value);
8+
// eslint-disable-next-line no-param-reassign
9+
root = newNode;
10+
return root;
11+
}
12+
13+
if (value < root.value) {
14+
// eslint-disable-next-line no-param-reassign
15+
root.leftChild = this.insert(root.leftChild, value);
16+
return root;
17+
}
18+
if (value > root.value) {
19+
// eslint-disable-next-line no-param-reassign
20+
root.rightChild = this.insert(root.rightChild, value);
21+
return root;
22+
}
23+
},
24+
25+
preorder(root) {
26+
/** returning an array so as to make testing easy */
27+
let arr = [];
28+
if (root === null) return [];
29+
arr.push(root.value);
30+
31+
const left = this.preorder(root.leftChild);
32+
arr = [...arr, ...left];
33+
34+
const right = this.preorder(root.rightChild);
35+
arr = [...arr, ...right];
36+
return arr;
37+
},
38+
39+
inorder(root) {
40+
/** left - root - right */
41+
if (root === null) return [];
42+
let arr = [];
43+
const left = this.inorder(root.leftChild);
44+
arr = [...left, ...arr];
45+
46+
// print root
47+
arr = [...arr, root.value];
48+
49+
const right = this.inorder(root.rightChild);
50+
arr = [...arr, ...right];
51+
return arr;
52+
},
53+
54+
postorder(root) {
55+
/** left - right - root */
56+
57+
if (root === null) return [];
58+
let arr = [];
59+
60+
const left = this.postorder(root.leftChild);
61+
arr = [...left, ...arr];
62+
63+
const right = this.postorder(root.rightChild);
64+
arr = [...arr, ...right];
65+
66+
return [...arr, root.value];
67+
},
68+
69+
search(root, value) {
70+
if (root === null) return false;
71+
if (value === root.value) return true;
72+
73+
if (value < root.value) {
74+
return this.search(root.leftChild, value);
75+
}
76+
if (value > root.value) {
77+
return this.search(root.rightChild, value);
78+
}
79+
return false;
80+
},
81+
82+
delete(root, value) {
83+
if (root === null) {
84+
return root;
85+
}
86+
87+
if (value > root.value) {
88+
// eslint-disable-next-line no-param-reassign
89+
root.rightChild = this.delete(root.rightChild, value);
90+
} else if (value < root.value) {
91+
// eslint-disable-next-line no-param-reassign
92+
root.leftChild = this.delete(root.leftChild, value);
93+
} else {
94+
// found the node
95+
if (root.leftChild === null) {
96+
// there is a right sub-tree
97+
return root.rightChild;
98+
}
99+
if (root.rightChild === null) {
100+
// there is a left sub-tree
101+
return root.leftChild;
102+
}
103+
/**
104+
* the root contain 2 childs, we got 2 options:
105+
* 1. We can either find the Node with minimum value at from the right sub-tree
106+
* 2. Or, we can find the Node with maximum value from the left sub-tree
107+
*
108+
* I'm picking up 1 here
109+
*/
110+
const minRightNode = this.findMinNode(root.rightChild);
111+
// eslint-disable-next-line no-param-reassign
112+
root.value = minRightNode.value;
113+
// eslint-disable-next-line no-param-reassign
114+
root.rightChild = this.delete(root.rightChild, minRightNode.value);
115+
return root;
116+
}
117+
return root;
118+
},
119+
120+
findMinNode(root) {
121+
/** The minnimum values is the let most leaf node in BST */
122+
if (root.leftChild === null) return root;
123+
return this.findMinNode(root.leftChild);
124+
},
125+
126+
findMaxNode(root) {
127+
if (root.rightChild === null) return root;
128+
return this.findMaxNode(root.rightChild);
129+
},
130+
};
131+
132+
module.exports = utils;

0 commit comments

Comments
 (0)