|
1 | 1 | /* eslint-disable consistent-return */
|
2 | 2 | const Node = require('./Node');
|
| 3 | +const BSTUtils = require('./utils'); |
3 | 4 |
|
4 | 5 | class BinarySearchTree {
|
5 | 6 | constructor(value) {
|
6 | 7 | if (!value) throw new Error('Root node value required');
|
7 | 8 | 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; |
133 | 10 | }
|
134 | 11 |
|
135 | 12 | isEmpty() {
|
136 | 13 | return this.root === null;
|
137 | 14 | }
|
138 | 15 |
|
139 |
| - /** Layered methods to simplify the BST API */ |
| 16 | + /** Layered methods to simplify the BST API using utils under the hood */ |
140 | 17 |
|
141 | 18 | add(value) {
|
142 |
| - return this.insert(this.root, value); |
| 19 | + return this.BSTUtils.insert(this.root, value); |
143 | 20 | }
|
144 | 21 |
|
145 |
| - traversePreorder() { |
146 |
| - return this.preorder(this.root); |
| 22 | + preorder() { |
| 23 | + return this.BSTUtils.preorder(this.root); |
147 | 24 | }
|
148 | 25 |
|
149 | 26 | traversePostorder() {
|
150 |
| - return this.postorder(this.root); |
| 27 | + return this.BSTUtils.postorder(this.root); |
151 | 28 | }
|
152 | 29 |
|
153 | 30 | traverseInorder() {
|
154 |
| - return this.inorder(this.root); |
| 31 | + return this.BSTUtils.inorder(this.root); |
155 | 32 | }
|
156 | 33 |
|
157 | 34 | searchFor(value) {
|
158 |
| - return this.search(this.root, value); |
| 35 | + return this.BSTUtils.search(this.root, value); |
159 | 36 | }
|
160 | 37 |
|
161 | 38 | getMinimum() {
|
162 |
| - const minNode = this.findMinNode(this.root); |
| 39 | + const minNode = this.BSTUtils.findMinNode(this.root); |
163 | 40 | return minNode.value;
|
164 | 41 | }
|
165 | 42 |
|
166 | 43 | getMaximum() {
|
167 |
| - const maxNode = this.findMaxNode(this.root); |
| 44 | + const maxNode = this.BSTUtils.findMaxNode(this.root); |
168 | 45 | return maxNode.value;
|
169 | 46 | }
|
170 | 47 |
|
171 | 48 | remove(value) {
|
172 |
| - this.root = this.delete(this.root, value); |
| 49 | + this.root = this.BSTUtils.delete(this.root, value); |
173 | 50 | }
|
174 | 51 | }
|
175 | 52 |
|
|
0 commit comments