1+ ( function ( ) {
2+ /**
3+ * function to create tree node
4+ * @param {* } data
5+ */
6+ const Node = function ( data = null ) {
7+ this . data = data ;
8+ this . left = null ;
9+ this . right = null ;
10+ }
11+
12+ const BinarySearchTree = function ( ) {
13+ let root = null ;
14+ let traversalResult = [ ] ;
15+ // function to insert node in the tree
16+ const insert = data => {
17+ const node = new Node ( data ) ;
18+ root ? insertNode ( root , node ) : root = node ;
19+ }
20+
21+ // helper function to locate the node position to insert in the tree
22+ const insertNode = ( parentNode , node ) => {
23+ if ( node . data < parentNode . data ) {
24+ if ( parentNode . left === null ) {
25+ parentNode . left = node ;
26+ } else {
27+ insertNode ( parentNode . left , node )
28+ }
29+ } else {
30+ if ( parentNode . right === null ) {
31+ parentNode . right = node ;
32+ } else {
33+ insertNode ( parentNode . right , node )
34+ }
35+ }
36+ }
37+
38+ // function to remove the node with data in argument and updates the root node
39+ const remove = data => {
40+ root = removeNode ( root , data ) ;
41+ }
42+
43+ // helper function to locate the node matching the data and remove and update the branch
44+ const removeNode = ( parentNode , data ) => {
45+ if ( parentNode === null ) {
46+ return parentNode ;
47+ } else if ( data < parentNode . data ) {
48+ parentNode . left = removeNode ( parentNode . left , data ) ;
49+ return parentNode ;
50+ } else if ( data > parentNode . data ) {
51+ parentNode . right = removeNode ( parentNode . right , data ) ;
52+ return parentNode ;
53+ } else {
54+ const { left, right } = parentNode ;
55+ if ( left === null && right === null ) {
56+ parentNode = null ;
57+ return parentNode ;
58+ }
59+
60+ if ( left === null ) {
61+ parentNode = parentNode . right ;
62+ return parentNode ;
63+ } else if ( right === null ) {
64+ parentNode = parentNode . left ;
65+ return parentNode ;
66+ }
67+
68+ // find minRightNode value and replace the parentNode value with that
69+ const minRightNode = findMinNode ( parentNode . right ) ;
70+ parentNode . data = minRightNode . data ;
71+ // then remove the minRightNode from the right sub tree
72+ parentNode . right = removeNode ( parentNode . right , minRightNode . data ) ;
73+ return parentNode ;
74+ }
75+ }
76+
77+ // finds the minimum node in tree
78+ // searching starts from given node
79+ const findMinNode = node => {
80+ // if left of a node is null
81+ // then it must be minimum node
82+ if ( node . left === null )
83+ return node ;
84+ else
85+ return findMinNode ( node . left ) ;
86+ }
87+
88+ // function to search for a node with given data
89+ // this method uses depth first algorithm
90+ const search = ( data , parentNode = root ) => {
91+ // if trees is empty return null
92+ if ( parentNode === null ) {
93+ return null ;
94+ }
95+ // if data is less than node's data
96+ // move left
97+ else if ( data < parentNode . data ) {
98+ return search ( parentNode . left , data ) ;
99+ }
100+ // if data is less than node's data
101+ // move left
102+ else if ( data > parentNode . data ) {
103+ return search ( parentNode . right , data ) ;
104+ }
105+ // if data is equal to the node data
106+ // return parentNode
107+ else {
108+ return parentNode ;
109+ }
110+ }
111+
112+ // returns root of the tree
113+ const getRootNode = ( ) => root ;
114+
115+ const traversalMode = {
116+ 'inorder' : Symbol ( 'inorder' ) ,
117+ 'preorder' : Symbol ( 'preorder' ) ,
118+ 'postorder' : Symbol ( 'postorder' )
119+ } ;
120+
121+ const inOrderTraversal = ( node ) => {
122+ if ( node !== null ) {
123+ inOrderTraversal ( node . left ) ;
124+ traversalResult . push ( node . data ) ;
125+ inOrderTraversal ( node . right ) ;
126+ }
127+ }
128+
129+ const preOrderTraversal = ( node ) => {
130+ if ( node !== null ) {
131+ traversalResult . push ( node . data ) ;
132+ preOrderTraversal ( node . left ) ;
133+ preOrderTraversal ( node . right ) ;
134+ }
135+ }
136+
137+ const postOrderTraversal = ( node ) => {
138+ if ( node !== null ) {
139+ postOrderTraversal ( node . left ) ;
140+ postOrderTraversal ( node . right ) ;
141+ traversalResult . push ( node . data ) ;
142+ }
143+ }
144+
145+ const traversal = ( mode = traversalMode . inorder , node = root ) => {
146+ traversalResult = [ ] ;
147+ switch ( mode ) {
148+ case traversalMode . inorder :
149+ inOrderTraversal ( node ) ;
150+ break ;
151+ case traversalMode . preorder :
152+ preOrderTraversal ( node ) ;
153+ break ;
154+ case traversalMode . postorder :
155+ postOrderTraversal ( node ) ;
156+ break ;
157+ }
158+ return traversalResult . join ( ' -> ' ) ;
159+ }
160+
161+ return Object . freeze ( {
162+ insert,
163+ remove,
164+ traversal,
165+ traversalMode,
166+ getRootNode,
167+ search
168+ } ) ;
169+ }
170+
171+ const bst = new BinarySearchTree ( ) ;
172+ console . log ( 'Inserting nodes to the BinarySearchTree' ) ;
173+ bst . insert ( 15 ) ;
174+ bst . insert ( 25 ) ;
175+ bst . insert ( 10 ) ;
176+ bst . insert ( 7 ) ;
177+ bst . insert ( 22 ) ;
178+ bst . insert ( 17 ) ;
179+ bst . insert ( 13 ) ;
180+ bst . insert ( 5 ) ;
181+ bst . insert ( 9 ) ;
182+ bst . insert ( 27 ) ;
183+ console . log ( 'tree result after insertion' ) ;
184+ console . log ( JSON . stringify ( bst . getRootNode ( ) , 0 , 4 ) ) ;
185+ console . log ( 'inorder traversal from root node' ) ;
186+ console . log ( bst . traversal ( bst . traversalMode . inorder ) ) ;
187+ console . log ( 'preorder traversal from root node' ) ;
188+ console . log ( bst . traversal ( bst . traversalMode . preorder ) ) ;
189+ console . log ( 'postorder traversal from root node' ) ;
190+ console . log ( bst . traversal ( bst . traversalMode . postorder ) ) ;
191+
192+ console . log ( 'Removing node with no children - 5' ) ;
193+ bst . remove ( 5 ) ;
194+ console . log ( 'inorder traversal from root node after removing 5' ) ;
195+ console . log ( bst . traversal ( bst . traversalMode . inorder ) ) ;
196+
197+ console . log ( 'Removing node with one children - 7' ) ;
198+ bst . remove ( 7 ) ;
199+ console . log ( 'inorder traversal from root node after removing 7' ) ;
200+ console . log ( bst . traversal ( bst . traversalMode . inorder ) ) ;
201+
202+ console . log ( 'Removing node with two children - 15' ) ;
203+ bst . remove ( 15 ) ;
204+ console . log ( 'inorder traversal from root node after removing 15' ) ;
205+ console . log ( bst . traversal ( bst . traversalMode . inorder ) ) ;
206+ console . log ( 'preorder traversal from root node after removing 15' ) ;
207+ console . log ( bst . traversal ( bst . traversalMode . preorder ) ) ;
208+ console . log ( 'postorder traversal from root node after removing 15' ) ;
209+ console . log ( bst . traversal ( bst . traversalMode . postorder ) ) ;
210+ console . log ( 'tree result after removing 5, 7 and 15' ) ;
211+ console . log ( JSON . stringify ( bst . getRootNode ( ) , 0 , 4 ) ) ;
212+ } ) ( ) ;
0 commit comments