|
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