### Traversing/searching in a BST

• Recall: how to traverse a BST to find a node (with a specific value)

• Example: how to find the node with the value 7:

• Start at the root node:

Since 7 > 3, search in the right subtree

• Continue:

Since 7 > 6, search in the right subtree

• Continue:

Since 7 < 9, search in the left subtree

 Node with value 7 has been found !!!

• Preparing to traverse a Binary Search Tree to search for a node

• Pay attention to the links in the Binary Search Tree:

We must use the correct links to traverse the nodes in the BST.

• Important warning:

• Never change the root variable when you traverse a Binary Search Tree

 Because if you update the root variable, you will not be able to access the Binary Search Tree the second time

• Rule:

 Always use an auxiliary variable to perform the traversal !!!

• Statements in Java that prepares for the tree traversal:

 ``` Node curr_node; // Help variable to perform the tree traversal curr_node = root; // Start at the root node ```

Result:

(Note: I abbreviated the name of the auxiliary variable in all the figures to save space)

• Current node in the traversal

• Notation:

 Current node = the node that is currently pointed to by the auxiliary traversal variable (curr_node)

• Moving to (visiting) the left child node of the current node

• The statement:

 ``` curr_node = curr_node.left; ```

will change the current node to the

 left child node of the current node

Example:

• Before we execute the statement:

• After we executed curr_node = curr_node.left:

• Moving to (visiting) the right child node of the current node

• The statement:

 ``` curr_node = curr_node.right; ```

will change the current node to the

 right child node of the current node

Example:

• Before we execute the statement:

• After we executed curr_node = curr_node.right:

• Traversing a Binary Search Tree to find a node with a specific value

• Psuedo code:

 ``` /* =========================================================== findNode(x): return the reference to a Node that contain the value x (if x is found in the BST) returns "null" if x is not found =========================================================== */ Node findNode( double x ) { Node curr_node; // Help variable curr_node = root; // start searching at the root node while ( curr_node has not reached the "end" of the tree ) { if ( x is equal to curr_node.value ) { return curr_node; // Found ! } else if ( x < curr_node.value ) { search further in the left tree } else // This must be true: ( x > curr_node.value ) { search further in the right tree } } /* ============================================ When program reaches here, x is NOT in BST =========================================== */ return null; // Return not found } ```

• In Java:

 ``` public Node findNode(double x) { Node curr_node; // Help variable /* ------------------------------------------------- Find the node with search value == "x" in the BST ------------------------------------------------- */ curr_node = root; // Always start at the root node while ( curr_node != null ) { if ( x == curr_node.value ) { // Found search value in BST return curr_node; } else if ( x < curr_node.value ) { curr_node = curr_node.left; // Continue search in left subtree } else // This must be true: ( x > curr_node.value ) { curr_node = curr_node.right; // Continue search in right subtree } } /* ====================================== When we reach here, x is NOT in BST ====================================== */ return null; // Return not found } ```

• An augmented findNode() method

• Recall:

• When we insert a node into a linked list, we must update the previous node in the list !!!

Example:

• The list before insert(9):

• The list after insert(9):

• Similarly:

 We will need to update the previous node in the BST when we insert/remove a node in a BST

Here is an augmented version of the findNode() method that records the previous node of the current node:

 ``` public Node myParent; // Used by findNode() to save the previous node public Node findNode(double x) { Node curr_node; // Points to the current node Node prev_node; // Points to the previous node /* -------------------------------------------- Find the node with search value == "x" in the BST -------------------------------------------- */ curr_node = root; // Always start at the root node prev_node = root; // Remember the previous node for insertion while ( curr_node != null ) { if ( x == curr_node.value ) { // Found search value in BST myParent = prev_node; // Save in myParent return curr_node; } else if ( x < curr_node.value ) { prev_node = curr_node; // Remember prev. node curr_node = curr_node.left; // Continue search in left subtree } else // This must be true: ( x > curr_node.value ) { prev_node = curr_node; // Remember prev. node curr_node = curr_node.right; // Continue search in right subtree } } /* ====================================== When we reach here, x is NOT in BST ====================================== */ myParent = prev_node; // Save in myParent return null; // Return not found } ```

• How does the augmented findNode(x) work

• Fact 1:

 findNode(x) will return the reference to the node containing the value x if found In this case, the variable myParent will point to the parent node of the node that contains x

Example: find the node with the value 7:

• Initially, curr_node and prev_node will point to the root node:

Since 7 > 3, we execute these statements in findNode():

 ``` prev_node = curr_node; // Remember prev. node curr_node = curr_node.right; // Continue search in right subtree ```

• Result:

Since 7 > 6, we execute these statements in findNode():

 ``` prev_node = curr_node; // Remember prev. node curr_node = curr_node.right; // Continue search in right subtree ```

• Result:

Since 7 < 9, we execute these statements in findNode():

 ``` prev_node = curr_node; // Remember prev. node curr_node = curr_node.left; // Continue search in left subtree ```

• Result:

• We have found the node with value 7

Notice that:

 The variable myParent (which is equal to prev_node) points to the parent node of the node that contains the value 7

• Fact 2:

 findNode(x) will return the null if x is not found More importantly, in this case, the variable myParent will point to the node that you can use as parent node to insert x

Example: find the node with the value 10:

• Initially, curr_node and prev_node will point to the root node:

Since 10 > 3, we execute these statements in findNode():

 ``` prev_node = curr_node; // Remember prev. node curr_node = curr_node.right; // Continue search in right subtree ```

• Result:

Since 10 > 6, we execute these statements in findNode():

 ``` prev_node = curr_node; // Remember prev. node curr_node = curr_node.right; // Continue search in right subtree ```

• Result:

Since 10 > 9, we execute these statements in findNode():

 ``` prev_node = curr_node; // Remember prev. node curr_node = curr_node.right; // Continue search in left subtree ```

• Result:

• Since curr_node == null, the algorithm terminates (and returns null for "not found")

More importantly, notice that:

• The variable myParent (which is equal to prev_node) points the node that can be used as parent node for the value 10: