GVSU CIS 263
Week 5 / Day 2
Trees
- Binary Tree: Like a list, but with two “next” nodes
- Terms
- Leaf
- Internal node
- Parent
- Root
- Depth: Number of edges on path to root.
- (Root has depth 0)
- Height is maximum depth
- (A tree with just one node has depth 0)
- “Full”: Every node contains 0 or two children
- “Complete”: All levels except the last are full
- “Perfect”: All levels, including the last, are full.
- Binary trees have at most two children. Trees in general can have any number of children.
- File system.
- Binary search tree: Smaller items go left, larger items go right.
- Search
- Implement search algorithm.z
-
BSTSearch(tree, key) { cur = tree->root while (cur is not null) if (key == cur->key) return cur // Found else if (key < cur->key) cur = cur->left else cur = cur->right return null // Not found }
-
- Implement search algorithm recursively.
-
bool contains( const Comparable & x, BinaryNode *t ) const { if( t == nullptr ) return false; else if( x < t->element ) return contains( x, t->left ); else if( t->element < x ) return contains( x, t->right ); else return true; // Match }
-
- What is the worst-case run time?
- Implement search algorithm.z
- Insert
- Implement
insert
-
BSTInsert(tree, node) { if (tree->root is null) tree->root = node node->left = null node->right = null else cur = tree->root while (cur is not null) if (node->key < cur->key) if (cur->left is null) cur->left = node cur = null else cur = cur->left else if (cur->right is null) cur->right = node cur = null else cur = cur->right node->left = null node->right = null }
-
- Implement insert recursively
-
void insert( const Comparable & x, BinaryNode * & t ) { if( t == nullptr ) t = new BinaryNode{ x, nullptr, nullptr }; else if( x < t->element ) insert( x, t->left ); else if( t->element < x ) insert( x, t->right ); else ; // Duplicate; do nothing }
-
- Implement
- Remove
- What are the different cases?
- Removing leaf
- Removing internal node with one child
- Removing internal node with two children
- Draw a picture of each scenario (and what should happen)
- Leaf is just removed
- Internal node with one child: just wire child up to the parent
- Internal node with two childen:
- Move data from leftmost node of right child.
- Delete the copied node.
- Why does the two-child technique work?
-
TRemove(tree, key) { par = null cur = tree->root while (cur is not null) { // Search for node if (cur->key == key) { // Node found if (!cur->left && !cur->right) { // Remove leaf if (!par) // Node is root tree->root = null else if (par->left == cur) par->left = null else par->right = null } else if (cur->left && !cur->right) { // Remove node with only left child if (!par) // Node is root tree->root = cur->left else if (par->left == cur) par->left = cur->left else par->right = cur->left } else if (!cur->left && cur->right) { // Remove node with only right child if (!par) // Node is root tree->root = cur->right else if (par->left == cur) par->left = cur->right else par->right = cur->right } else { // Remove node with two children // Find successor (leftmost child of right subtree) suc = cur->right while (suc->left is not null) suc = suc->left successorData = Create copy of suc's data BSTRemove(tree, suc->key) // Remove successor Assign cur's data with successorData } return // Node found and removed } else if (cur->key < key) { // Search right par = cur cur = cur->right } else { // Search left par = cur cur = cur->left } } return // Node not found }
- Notice the use of a reference to a pointer:
-
void remove( const Comparable & x, BinaryNode * & t ) { if( t == nullptr ) return; // Item not found; do nothing if( x < t->element ) remove( x, t->left ); else if( t->element < x ) remove( x, t->right ); else if( t->left != nullptr && t->right != nullptr ) // Two children { t->element = findMin( t->right )->element; remove( t->element, t->right ); } else { BinaryNode *oldNode = t; t = ( t->left != nullptr ) ? t->left : t->right; delete oldNode; } }
-
- What are the different cases?
- Traversal
- Pre-order
- Post-order
- In-order
- When is each used?
- Show expression tree
- Show file system with a pre-order traversal
- What is the key to preserving
log(n)
runtime? - How do we do that?
- Binary Tree source from Weiss https://users.cs.fiu.edu/~weiss/dsaa_c++4/code/BinarySearchTree.h