Binary Search Trees Notes
Basic Concepts and Binary Search Trees
- Linear list structures: Arrays vs. linked lists.
- Involve search, insertion, and deletion algorithms.
- Binary Search Trees (BST):
- Efficient for searching, inserting, and deleting data.
- A BST is a binary tree with specific properties:
- All items in the left subtree are less than the root.
- All items in the right subtree are greater than or equal to the root.
- Each subtree is itself a binary search tree.
BST Structure and Balance
- Key Property: In a binary search tree:
- All nodes in the left subtree are less than the root node (All < K).
- All nodes in the right subtree are greater than the root node (All > K).
- Tree Completeness and Balance:
- Complete and balanced trees: (a) and (b) are examples.
- Nearly complete and balanced tree: (d) is an example.
- Neither complete nor balanced trees: (c) and (e) are examples.
Invalid Binary Search Trees
- Figure 7-3 illustrates examples of invalid binary search trees.
- The key property of BSTs (left subtree < root < right subtree) must always hold.
BST Operations
- There are four basic BST operations:
- Traversal
- Search
- Insert
- Delete
Tree Traversals
- Preorder Traversal:
- Visit the root first, then the left subtree, then the right subtree.
- Example: 23 18 12 20 44 35 52
- Postorder Traversal:
- Visit the left subtree first, then the right subtree, then the root.
- Example: 12 20 18 35 52 44 23
- Inorder Traversal:
- Visit the left subtree first, then the root, then the right subtree.
- Example: 12 18 20 23 35 44 52
- Inorder traversal produces a sequenced (sorted) list.
Right-Node-Left Traversal
- Right-Node-Left Traversal:
- Visit the right subtree first, then the root, then the left subtree.
- Example: 52 44 35 23 20 18 12
- Right-node-left traversal of a binary search tree produces a descending sequence.
Searches in BST
- Three types of searches:
- Find the smallest node
- Find the largest node
- Find a requested node
Finding the Smallest Node
- Algorithm 7-1: findSmallestBST(root)
- Objective: Finds the smallest node in a BST.
- Precondition:
root is a pointer to a nonempty BST or subtree. - Returns: Address of the smallest node.
- Steps:
- If the left subtree is empty, return the current node (root).
- Otherwise, recursively call
findSmallestBST on the left subtree.
Finding the Largest Node
- Algorithm 7-2: findLargestBST(root)
- Objective: Finds the largest node in a BST.
- Precondition:
root is a pointer to a nonempty BST or subtree. - Returns: Address of the largest node.
- Steps:
- If the right subtree is empty, return the current node (root).
- Otherwise, recursively call
findLargestBST on the right subtree.
Binary Tree Search
- BST Search:
- Locates a specific node in the tree.
- Comparison to Sequenced Array:
- BST search resembles a binary search algorithm.
BST Search Algorithm
- Algorithm 7-3: searchBST (root, targetKey)
- Objective: Search a binary search tree for a given value.
- Preconditions:
root is the root to a binary tree or subtree.targetKey is the key value being searched for.
- Returns:
- The node address if the value is found.
null if the node is not in the tree.
- Steps:
- If the tree is empty, return
null (value not found). - If
targetKey is less than the current node's key (root), recursively call searchBST on the left subtree. - If
targetKey is greater than the current node's key (root), recursively call searchBST on the right subtree. - Otherwise, the
targetKey is equal to the current node's key; return the current node (root).
BST Insertion
- Insertion Process:
- Follow the branches of the tree to find an empty subtree where the new node can be inserted.
- Insertions typically occur at a leaf node or a 'leaflike' node (a node with only one null subtree).
BST Insertion Examples
- Example scenarios of inserting nodes into a BST.
- Figures 7-8 (a) and (b) demonstrate inserting 19.
- Figures 7-8 (c) and (d) demonstrate inserting 38.
BST Insertion Algorithm
- Algorithm 7-4: addBST (root, newNode)
- Objective: Insert a node containing new data into the BST using recursion.
- Preconditions:
root is the address of the current node in the BSTnewNode is the address of the node to be inserted.
- Postcondition:
newNode is inserted into the tree. - Returns: Address of the potential new tree root.
- Steps:
- If the tree is empty, set
root to newNode and return newNode - Locate a null subtree for insertion:
- If
newNode is less than root, recursively call addBST on the left subtree. - Otherwise, recursively call
addBST on the right subtree.
BST Deletion
- Deletion Cases: There are four possible cases when deleting a node:
- Case 1: The node to be deleted has no children (it's a leaf node).
- Solution: Simply delete the node.
- Case 2: The node to be deleted has only a right subtree.
- Solution: Delete the node and attach the right subtree to the deleted node’s parent.
- Case 3: The node to be deleted has only a left subtree.
- Solution: Delete the node and attach the left subtree to the deleted node’s parent.
- Case 4: The node to be deleted has two subtrees.
- Deleting a node from the middle of a tree can create unbalanced trees.
BST Deletion Strategy
- Objective: Maintain the existing structure of the BST as much as possible.
- Method: Find a suitable data value to replace the deleted node's data.
- Two possible approaches:
- Find the largest node in the deleted node’s left subtree and move its data to replace the deleted node’s data.
- Find the smallest node in the deleted node’s right subtree and move its data to replace the deleted node’s data.
BST Deletion Algorithm
- Algorithm deleteBST (root, dltkey)
- Objective: Deletes a node from a BST.
- Preconditions:
root is a reference to the node to be deleted.dltkey is the key of the node to be deleted.
- Postconditions:
- Node deleted if found.
- If
dltkey not found, root remains unchanged.
- Returns:
true if node deleted, false if not found. - Steps:
- If the tree is empty, return
false. - If
dltkey is less than the current node's key, recursively call deleteBST on the left subtree. - Else if
dltkey is greater than the current node's key, recursively call deleteBST on the right subtree. - Else (node to be deleted is found):
- Test for leaf node:
- If there is no left subtree, make the right subtree the root and return
true. - Else if there is no right subtree, make the left subtree the root and return
true. - Else (node to be deleted is not a leaf):
- Find the largest node on the left subtree.
- Save the root in
deleteNode. - Set
largest to the largest node in the left subtree (using largestBST function). - Move the data in
largest to deleteNode. - Recursively call
deleteBST on the left subtree of deleteNode to delete the now-moved key of largest.
Threaded Trees
- Background:
- Binary tree traversal algorithms typically use recursion or programmer-written stacks.
- Using stacks can be more efficient than recursion for frequent traversals.
- A threaded tree presents a third alternative.
- Definition:
- In a threaded tree, null pointers are replaced with pointers to their successor nodes in a specific traversal order (e.g., inorder).
Building and Traversing Threaded Trees
- Building a Threaded Tree:
- Build a standard binary search tree.
- Traverse the tree and change the null right pointers to point to their inorder successors.
- Traversal:
- Locate the far-left node (the first node in the inorder traversal).
- Loop, following the thread (the right pointer) to the next node.
- Continue until a null thread (right pointer) is encountered, indicating the end of the traversal.
- Advantages:
- No recursion or stack is needed for traversal.
- Straightforward and efficient traversal process.