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 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

Lines changed: 12 additions & 135 deletions
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

Lines changed: 132 additions & 0 deletions
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)

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /