Chapter 10 Trees 1
Definition of Tree • A tree is a set of linked nodes, such that there is one and only one path from a unique node (called the root node) to every other node in the tree. • A path exists from node A to node B if one can follow a chain of pointers to travel from node A to node B. 2
Paths A set of linked nodes D F A G E B There is one path from A to B C There is a path from D to B There is also a second path from D to B. 3
Paths (cont.) D F A G E B C There is no path from C to any other node. 4
Cycles • There is no cycle (circle of pointers) in a tree. • Any linked structure that has a cycle would have more than one path from the root node to another node. 5
Example of a Cycle D A B C E C→D→B→E→C 6
Tree Cannot Have a Cycle D A B C E 2 paths exist from A to C: 1. A → C 2. A → C → D → B → E → C 7
Example of a Tree In a tree, every root pair of linked A nodes have a parent-child relationship (the C B D parent is closer to the root) G E F 8
Example of a Tree (cont.) root For example, C is a A parent of G C B D G E F 9
Example of a Tree (cont.) root A E and F are children of D C B D G E F 10
Example of a Tree (cont.) The root node is the root A only node that has no parent. C B D G E F 11
Example of a Tree (cont.) Leaf nodes (or root leaves for short) A have no children. C B D G E F 12
Subtrees A subtree is a part of a tree root that is a tree in itself A B C I K D E F J G H subtree 13
Binary Trees • A binary tree is a tree in which each node can only have up to two children… 14
NOT a Binary Tree root C has 3 child nodes. A B C I K D E F J G H 15
Example of a Binary Tree The links in a tree root are often called A edges B C I K E J G H 16
Levels root level 0 A level 1 B C level 2 I K E level 3 J G H The level of a node is the number of edges in the path from the root node to this node 17
Full Binary Tree root A B C D E F G H I J K L M N O In a full binary tree, each node has two children except for the nodes on the last level, which are leaf nodes 18
Complete Binary Trees • A complete binary tree is a binary tree that is either – a full binary tree – OR – a tree that would be a full binary tree but it is missing the rightmost nodes on the last level 19
NOT a Complete Binary Trees root A B C D E F G H I Missing non-rightmost nodes on the last level 20
Complete Binary Trees (cont.) root A B C D E F G H I J K L Missing rightmost nodes on the last level 21
Complete Binary Trees (cont.) A full binary tree is also a complete binary root A tree. B C D E F G H I J K L M N O 22
Binary Search Trees • A binary search tree is a binary tree that allows us to search for values that can be anywhere in the tree. • Usually, we search for a certain key value, and once we find the node that contains it, we retrieve the rest of the info at that node. • Therefore, we assume that all values searched for in a binary search tree are distinct. 23
Properties of Binary Search Trees • A binary search tree does not have to be a complete binary tree. • For any particular node, – the key in its left child (if any) is less than its key. – the key in its right child (if any) is greater than its key. 24
Binary Search Tree Node The implementation template <typename T> of a binary search BSTNode { tree usually just T info; maintains a single BSTNode<T> *left; pointer in the private BSTNode<T> *right; section called }; root, to point to the root node. 25
Inserting Nodes Into a BST root: NULL BST starts off empty Objects that need to be inserted (only key values are shown): 37, 2, 45, 48, 41, 29, 20, 30, 49, 7 26
Inserting Nodes Into a BST (cont.) root 37 37, 2, 45, 48, 41, 29, 20, 30, 49, 7 27
Inserting Nodes Into a BST (cont.) root 37 2 < 37, so insert 2 on the left side of 37 2, 45, 48, 41, 29, 20, 30, 49, 7 28
Inserting Nodes Into a BST (cont.) root 37 2 2, 45, 48, 41, 29, 20, 30, 49, 7 29
Inserting Nodes Into a BST (cont.) root 37 2 45 > 37, so insert it at the right of 37 45, 48, 41, 29, 20, 30, 49, 7 30
Inserting Nodes Into a BST (cont.) root 37 45 2 45, 48, 41, 29, 20, 30, 49, 7 31
Inserting Nodes Into a BST (cont.) root 37 45 2 When comparing, we always start at the root node 48 > 37, so look to the right 48, 41, 29, 20, 30, 49, 7 32
Inserting Nodes Into a BST (cont.) root 37 45 2 This time, there is a node already to the right of the root node. We then compare 48 to this node 48 > 45, and 45 has no right child, so we insert 48 on the right of 45 48, 41, 29, 20, 30, 49, 7 33
Inserting Nodes Into a BST (cont.) root 37 45 2 48 48, 41, 29, 20, 30, 49, 7 34
Inserting Nodes Into a BST (cont.) root 37 45 2 41 > 37, so look to the right 48 41 < 45, so look to the left – there is no left child, so insert 41, 29, 20, 30, 49, 7 35
Inserting Nodes Into a BST (cont.) root 37 45 2 48 41 41, 29, 20, 30, 49, 7 36
Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 < 37, left 41 29 > 2, right 29, 20, 30, 49, 7 37
Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 29, 20, 30, 49, 7 38
Inserting Nodes Into a BST (cont.) root 37 45 2 48 20 < 37, left 29 41 20 > 2, right 20 < 29, left 20, 30, 49, 7 39
Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 20 20, 30, 49, 7 40
Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 30 < 37 20 30 > 2 30 > 29 30, 49, 7 41
Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 20 30 30, 49, 7 42
Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 49 > 37 49 > 45 20 30 49 > 48 49, 7 43
Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 20 30 49 49, 7 44
Inserting Nodes Into a BST (cont.) root 37 45 2 48 7 < 37 29 41 7>2 7 < 29 7 < 20 20 30 49 7 45
Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 20 30 49 7 7 46
Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 All elements have 20 30 49 been inserted 7 47
Searching for a Key in a BST root 37 45 2 48 29 41 Searching for a key in a BST uses 20 30 49 the same logic 7 Key to search for: 29 48
Searching for a Key in a BST (cont.) root 37 45 2 48 29 < 37 29 41 20 30 49 7 Key to search for: 29 49
Searching for a Key in a BST (cont.) root 37 45 2 48 29 > 2 29 41 20 30 49 7 Key to search for: 29 50
Searching for a Key in a BST (cont.) root 37 45 2 48 29 == 29 29 41 FOUND IT! 20 30 49 7 Key to search for: 29 51
Searching for a Key in a BST (cont.) root 37 45 2 48 29 41 20 30 49 7 Key to search for: 3 52
Searching for a Key in a BST (cont.) root 37 45 2 3 < 37 3>2 48 3 < 29 29 41 3 < 20 3<7 20 30 49 7 Key to search for: 3 53
Searching for a Key in a BST (cont.) root 37 45 2 When the child pointer you want to follow is set to NULL, the key 48 29 41 you are looking for is not in the BST 20 30 49 7 Key to search for: 3 54
Deleting a BST Node • Deleting a node in a BST is a little tricky – it has to be deleted so that the resulting structure is still a BST with each node greater than its left child and less than its right child. • Deleting a node is handled differently depending on whether the node: – has no children – has one child – has two children 55
Deletion Case 1: No Children root 37 45 2 48 29 41 Node 49 has no children – to 20 30 49 delete it, we just remove it 56
Deletion Case 1: No Children (cont.) root 37 45 2 48 29 41 20 30 57
Deletion Case 2: One Child root 37 45 2 48 29 41 Node 48 has one child – to delete 20 30 it, we just splice 49 it out 58
Deletion Case 2: One Child (cont.) root 37 45 2 48 29 41 Node 48 has one child – to delete 20 30 it, we just splice 49 it out 59
Deletion Case 2: One Child (cont.) root 37 45 2 29 41 20 30 49 60
Deletion Case 2: One Child (cont.) root 37 45 2 48 29 41 Another example: node 2 has one child 20 30 – to delete it we also 49 splice it out 61
Deletion Case 2: One Child (cont.) root 37 45 2 48 29 41 Another example: node 2 has one child 20 30 – to delete it we also 49 splice it out 62
Deletion Case 2: One Child (cont.) root 37 45 48 29 41 20 30 49 63
Deletion Case 3: Two Children root 37 45 2 48 29 41 Node 37 has two children… 20 30 49 64
Deletion Case 3: Two Children (cont.) root 37 45 2 48 29 41 to delete it, first we find the greatest 20 30 node in its left 49 subtree 65
Deletion Case 3: Two Children (cont.) root 37 45 2 First, we go to the left 48 29 41 once, then follow the right pointers as far as we 20 30 49 can 66
Deletion Case 3: Two Children (cont.) root 37 45 2 48 29 41 30 is the greatest 20 30 node in the left 49 subtree of node 37 67
Deletion Case 3: Two Children (cont.) root 37 45 2 48 29 41 Next, we copy the 20 30 object at node 30 49 into node 37 68
Deletion Case 3: Two Children (cont.) root 30 45 2 48 29 41 Finally, we delete the lower red node 20 using case 1 or 49 case 2 deletion 69
Deletion Case 3: Two Children (cont.) root 30 45 2 48 29 41 Let’s delete node 30 20 now 49 70
Deletion Case 3: Two Children (cont.) root 30 45 2 48 29 41 29 is the greatest node in the left subtree of 20 49 node 30 71
Deletion Case 3: Two Children (cont.) root 30 45 2 48 29 41 Copy the object at node 29 into node 30 20 49 72
Deletion Case 3: Two Children (cont.) root 29 45 2 48 29 41 This time, the lower red node has a child – to delete 20 49 it we use case 2 deletion 73
Deletion Case 3: Two Children (cont.) root 29 45 2 48 29 41 This time, the lower red node has a child – to delete 20 49 it we use case 2 deletion 74
Deletion Case 3: Two Children (cont.) root 29 45 2 48 41 20 49 75
Traversing a BST • There are 3 ways to traversal a BST (visit every node in BST): • 1. Preorder (parent → left → right) • 2. Inorder (left → parent → right) • 3. Postorder (left → right → parent) 76
Binary Search Tree Class Template 1 template <typename T> 2 class BinarySearchTree { 3 BSTNode *root; 4 void preOrderInternal (BST<T> *parent) { … } 5 void inOrderInternal (BST<T> *parent) { … } 6 void postOrderInternal (BST<T> *parent) { … } 7 void insertInternal (BST<T> *parent, 8 const T& newElement) { … } 9 bool searchInternal (const T& target, 10 T& foundElement) { … } 77
Binary Search Tree Class Template (cont.) 11 public: 12 BinarySearchTree() { … } 13 ~BinarySearchTree() { … } 14 bool isEmpty() { … } 15 void preOrderTraversal() { … } 16 void inOrderTraversal() { … } 17 void postOrderTraversal() { … } 18 void insert (T element) { … } 19 bool search (T element, T& foundElement) { … } 20 void makeEmpty() { … } 21 } 78
Constructor, Destructor, IsEmpty() 1 BinarySearchTree() 2 : root(NULL) { } 3 4 ~BinarySearchTree() 5 { 6 makeEmpty(); 7 } 8 9 bool isEmpty() 10 { 11 return root == NULL: 12 } 79
Printing Elements In Order 2 void inOrderTraversal() The client uses the 3 { driver called 4 inOrderInternal (root); InOrderTraversal. 5 } The recursive function inOrderInternal is called. inOrderInternal prints all element in BST in sorted order, starting from root node. 80
Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { 5 inOrderInternal (parent->left); 6 cout << parent->info << " "; The base case 7 inOrderInternal (parent->right); occurs when 8 } parent is NULL – 9 } just returns. 81
Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { There are 2 5 inOrderInternal (parent->left); recursive calls under the if – the 6 cout << parent->info << " "; first advances 7 inOrderInternal (parent->right); the pointer to the 8 } left child… 9 } and the second advances the pointer to the right child. 82
Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { Each recursive 5 inOrderInternal (parent->left); call approaches 6 cout << parent->info << " "; the base case… 7 inOrderInternal (parent->right); it goes down one 8 } level through the 9 } tree, and it get closer to the case where parent->left or parent->right is NULL. 83
Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { If the BST contains 4 if (parent != NULL) { only one node, the 5 inOrderInternal (parent->left); root node is the only 6 cout << parent->info << " "; node – the left and 7 inOrderInternal (parent->right); right pointers of the 8 } root node will be set 9 } to NULL. 84
Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { parent->left is 5 inOrderInternal (parent->left); NULL, so NULL is passed into 6 cout << parent->info << " "; parent of the new 7 inOrderInternal (parent->right); inOrderInternal 8 } function. 9 } 85
Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { Since parent is 4 if (parent != NULL) { NULL in the new 5 inOrderInternal (parent->left); inOrderInternal 6 cout << parent->info << " "; function, it will 7 inOrderInternal (parent->right); return right away. 8 } 9 } 86
Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { parent->right is 5 inOrderInternal (parent->left); NULL – thus, 6 cout << parent->info << " "; the recursive 7 inOrderInternal (parent->right); function call immediately 8 } returns as 9 } before. 87
Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { 5 inOrderInternal (parent->left); 6 cout << parent->info << " "; 7 inOrderInternal (parent->right); 8 } 9 } In fact inOrderInternal works correctly when there is only 0, 1 or many node in the BST. 88
Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { 5 inOrderInternal (parent->left); 6 cout << parent->info << " "; 7 inOrderInternal (parent->right); 8 } 9 } inOrderInternal is called once from the driver inOrderTraversal. Then, for each node in the tree, 2 calls to inOrderInternal are made, giving us a total of 2n + 1 calls where n is the number of nodes. 89
Printing Elements Pre Order 2 void preOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { 5 cout << parent->info << " "; 6 preOrderInternal (parent->left); 7 preOrderInternal (parent->right); 8 } 9 } preOrderInternal prints the parent first. 90
Printing Elements Post Order 2 void postOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { 5 postOrderInternal (parent->left); 6 postOrderInternal (parent->right); 7 cout << parent->info << " "; 8 } 9 } postOrderInternal prints the parent last. 91
Searching and Insertion in BST 1 bool search (T target, T& foundElement) { 2 return searchInternal (root, target, foundElement); 3 } 4 5 void insert (const T& newElement) { 6 insertInternal (root, newElement); 7 } 92
Searching and Insertion in BST • We can actually figure out searchInternal and insertInternal using the same recursive logic as traversal in BST. 93
References • Childs, J. S. (2008). Trees. C++ Classes and Data Structures. Prentice Hall. 94

Lecture10 trees v3

  • 1.
    Chapter 10 Trees 1
  • 2.
    Definition of Tree •A tree is a set of linked nodes, such that there is one and only one path from a unique node (called the root node) to every other node in the tree. • A path exists from node A to node B if one can follow a chain of pointers to travel from node A to node B. 2
  • 3.
    Paths A set oflinked nodes D F A G E B There is one path from A to B C There is a path from D to B There is also a second path from D to B. 3
  • 4.
    Paths (cont.) D F A G E B C There is no path from C to any other node. 4
  • 5.
    Cycles • There isno cycle (circle of pointers) in a tree. • Any linked structure that has a cycle would have more than one path from the root node to another node. 5
  • 6.
    Example of aCycle D A B C E C→D→B→E→C 6
  • 7.
    Tree Cannot Havea Cycle D A B C E 2 paths exist from A to C: 1. A → C 2. A → C → D → B → E → C 7
  • 8.
    Example of aTree In a tree, every root pair of linked A nodes have a parent-child relationship (the C B D parent is closer to the root) G E F 8
  • 9.
    Example of aTree (cont.) root For example, C is a A parent of G C B D G E F 9
  • 10.
    Example of aTree (cont.) root A E and F are children of D C B D G E F 10
  • 11.
    Example of aTree (cont.) The root node is the root A only node that has no parent. C B D G E F 11
  • 12.
    Example of aTree (cont.) Leaf nodes (or root leaves for short) A have no children. C B D G E F 12
  • 13.
    Subtrees A subtree is a part of a tree root that is a tree in itself A B C I K D E F J G H subtree 13
  • 14.
    Binary Trees • Abinary tree is a tree in which each node can only have up to two children… 14
  • 15.
    NOT a BinaryTree root C has 3 child nodes. A B C I K D E F J G H 15
  • 16.
    Example of aBinary Tree The links in a tree root are often called A edges B C I K E J G H 16
  • 17.
    Levels root level 0 A level 1 B C level 2 I K E level 3 J G H The level of a node is the number of edges in the path from the root node to this node 17
  • 18.
    Full Binary Tree root A B C D E F G H I J K L M N O In a full binary tree, each node has two children except for the nodes on the last level, which are leaf nodes 18
  • 19.
    Complete Binary Trees •A complete binary tree is a binary tree that is either – a full binary tree – OR – a tree that would be a full binary tree but it is missing the rightmost nodes on the last level 19
  • 20.
    NOT a CompleteBinary Trees root A B C D E F G H I Missing non-rightmost nodes on the last level 20
  • 21.
    Complete Binary Trees (cont.) root A B C D E F G H I J K L Missing rightmost nodes on the last level 21
  • 22.
    Complete Binary Trees (cont.) A full binary tree is also a complete binary root A tree. B C D E F G H I J K L M N O 22
  • 23.
    Binary Search Trees •A binary search tree is a binary tree that allows us to search for values that can be anywhere in the tree. • Usually, we search for a certain key value, and once we find the node that contains it, we retrieve the rest of the info at that node. • Therefore, we assume that all values searched for in a binary search tree are distinct. 23
  • 24.
    Properties of Binary Search Trees • A binary search tree does not have to be a complete binary tree. • For any particular node, – the key in its left child (if any) is less than its key. – the key in its right child (if any) is greater than its key. 24
  • 25.
    Binary Search Tree Node The implementation template <typename T> of a binary search BSTNode { tree usually just T info; maintains a single BSTNode<T> *left; pointer in the private BSTNode<T> *right; section called }; root, to point to the root node. 25
  • 26.
    Inserting Nodes Into a BST root: NULL BST starts off empty Objects that need to be inserted (only key values are shown): 37, 2, 45, 48, 41, 29, 20, 30, 49, 7 26
  • 27.
    Inserting Nodes Into a BST (cont.) root 37 37, 2, 45, 48, 41, 29, 20, 30, 49, 7 27
  • 28.
    Inserting Nodes Into a BST (cont.) root 37 2 < 37, so insert 2 on the left side of 37 2, 45, 48, 41, 29, 20, 30, 49, 7 28
  • 29.
    Inserting Nodes Into a BST (cont.) root 37 2 2, 45, 48, 41, 29, 20, 30, 49, 7 29
  • 30.
    Inserting Nodes Into a BST (cont.) root 37 2 45 > 37, so insert it at the right of 37 45, 48, 41, 29, 20, 30, 49, 7 30
  • 31.
    Inserting Nodes Into a BST (cont.) root 37 45 2 45, 48, 41, 29, 20, 30, 49, 7 31
  • 32.
    Inserting Nodes Into a BST (cont.) root 37 45 2 When comparing, we always start at the root node 48 > 37, so look to the right 48, 41, 29, 20, 30, 49, 7 32
  • 33.
    Inserting Nodes Into a BST (cont.) root 37 45 2 This time, there is a node already to the right of the root node. We then compare 48 to this node 48 > 45, and 45 has no right child, so we insert 48 on the right of 45 48, 41, 29, 20, 30, 49, 7 33
  • 34.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 48, 41, 29, 20, 30, 49, 7 34
  • 35.
    Inserting Nodes Into a BST (cont.) root 37 45 2 41 > 37, so look to the right 48 41 < 45, so look to the left – there is no left child, so insert 41, 29, 20, 30, 49, 7 35
  • 36.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 41 41, 29, 20, 30, 49, 7 36
  • 37.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 < 37, left 41 29 > 2, right 29, 20, 30, 49, 7 37
  • 38.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 29, 20, 30, 49, 7 38
  • 39.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 20 < 37, left 29 41 20 > 2, right 20 < 29, left 20, 30, 49, 7 39
  • 40.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 20 20, 30, 49, 7 40
  • 41.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 30 < 37 20 30 > 2 30 > 29 30, 49, 7 41
  • 42.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 20 30 30, 49, 7 42
  • 43.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 49 > 37 49 > 45 20 30 49 > 48 49, 7 43
  • 44.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 20 30 49 49, 7 44
  • 45.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 7 < 37 29 41 7>2 7 < 29 7 < 20 20 30 49 7 45
  • 46.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 20 30 49 7 7 46
  • 47.
    Inserting Nodes Into a BST (cont.) root 37 45 2 48 29 41 All elements have 20 30 49 been inserted 7 47
  • 48.
    Searching for a Key in a BST root 37 45 2 48 29 41 Searching for a key in a BST uses 20 30 49 the same logic 7 Key to search for: 29 48
  • 49.
    Searching for a Key in a BST (cont.) root 37 45 2 48 29 < 37 29 41 20 30 49 7 Key to search for: 29 49
  • 50.
    Searching for a Key in a BST (cont.) root 37 45 2 48 29 > 2 29 41 20 30 49 7 Key to search for: 29 50
  • 51.
    Searching for a Key in a BST (cont.) root 37 45 2 48 29 == 29 29 41 FOUND IT! 20 30 49 7 Key to search for: 29 51
  • 52.
    Searching for a Key in a BST (cont.) root 37 45 2 48 29 41 20 30 49 7 Key to search for: 3 52
  • 53.
    Searching for a Key in a BST (cont.) root 37 45 2 3 < 37 3>2 48 3 < 29 29 41 3 < 20 3<7 20 30 49 7 Key to search for: 3 53
  • 54.
    Searching for a Key in a BST (cont.) root 37 45 2 When the child pointer you want to follow is set to NULL, the key 48 29 41 you are looking for is not in the BST 20 30 49 7 Key to search for: 3 54
  • 55.
    Deleting a BSTNode • Deleting a node in a BST is a little tricky – it has to be deleted so that the resulting structure is still a BST with each node greater than its left child and less than its right child. • Deleting a node is handled differently depending on whether the node: – has no children – has one child – has two children 55
  • 56.
    Deletion Case 1: No Children root 37 45 2 48 29 41 Node 49 has no children – to 20 30 49 delete it, we just remove it 56
  • 57.
    Deletion Case 1: No Children (cont.) root 37 45 2 48 29 41 20 30 57
  • 58.
    Deletion Case 2: One Child root 37 45 2 48 29 41 Node 48 has one child – to delete 20 30 it, we just splice 49 it out 58
  • 59.
    Deletion Case 2: One Child (cont.) root 37 45 2 48 29 41 Node 48 has one child – to delete 20 30 it, we just splice 49 it out 59
  • 60.
    Deletion Case 2: One Child (cont.) root 37 45 2 29 41 20 30 49 60
  • 61.
    Deletion Case 2: One Child (cont.) root 37 45 2 48 29 41 Another example: node 2 has one child 20 30 – to delete it we also 49 splice it out 61
  • 62.
    Deletion Case 2: One Child (cont.) root 37 45 2 48 29 41 Another example: node 2 has one child 20 30 – to delete it we also 49 splice it out 62
  • 63.
    Deletion Case 2: One Child (cont.) root 37 45 48 29 41 20 30 49 63
  • 64.
    Deletion Case 3: Two Children root 37 45 2 48 29 41 Node 37 has two children… 20 30 49 64
  • 65.
    Deletion Case 3: Two Children (cont.) root 37 45 2 48 29 41 to delete it, first we find the greatest 20 30 node in its left 49 subtree 65
  • 66.
    Deletion Case 3: Two Children (cont.) root 37 45 2 First, we go to the left 48 29 41 once, then follow the right pointers as far as we 20 30 49 can 66
  • 67.
    Deletion Case 3: Two Children (cont.) root 37 45 2 48 29 41 30 is the greatest 20 30 node in the left 49 subtree of node 37 67
  • 68.
    Deletion Case 3: Two Children (cont.) root 37 45 2 48 29 41 Next, we copy the 20 30 object at node 30 49 into node 37 68
  • 69.
    Deletion Case 3: Two Children (cont.) root 30 45 2 48 29 41 Finally, we delete the lower red node 20 using case 1 or 49 case 2 deletion 69
  • 70.
    Deletion Case 3: Two Children (cont.) root 30 45 2 48 29 41 Let’s delete node 30 20 now 49 70
  • 71.
    Deletion Case 3: Two Children (cont.) root 30 45 2 48 29 41 29 is the greatest node in the left subtree of 20 49 node 30 71
  • 72.
    Deletion Case 3: Two Children (cont.) root 30 45 2 48 29 41 Copy the object at node 29 into node 30 20 49 72
  • 73.
    Deletion Case 3: Two Children (cont.) root 29 45 2 48 29 41 This time, the lower red node has a child – to delete 20 49 it we use case 2 deletion 73
  • 74.
    Deletion Case 3: Two Children (cont.) root 29 45 2 48 29 41 This time, the lower red node has a child – to delete 20 49 it we use case 2 deletion 74
  • 75.
    Deletion Case 3: Two Children (cont.) root 29 45 2 48 41 20 49 75
  • 76.
    Traversing a BST •There are 3 ways to traversal a BST (visit every node in BST): • 1. Preorder (parent → left → right) • 2. Inorder (left → parent → right) • 3. Postorder (left → right → parent) 76
  • 77.
    Binary Search Tree Class Template 1 template <typename T> 2 class BinarySearchTree { 3 BSTNode *root; 4 void preOrderInternal (BST<T> *parent) { … } 5 void inOrderInternal (BST<T> *parent) { … } 6 void postOrderInternal (BST<T> *parent) { … } 7 void insertInternal (BST<T> *parent, 8 const T& newElement) { … } 9 bool searchInternal (const T& target, 10 T& foundElement) { … } 77
  • 78.
    Binary Search Tree Class Template (cont.) 11 public: 12 BinarySearchTree() { … } 13 ~BinarySearchTree() { … } 14 bool isEmpty() { … } 15 void preOrderTraversal() { … } 16 void inOrderTraversal() { … } 17 void postOrderTraversal() { … } 18 void insert (T element) { … } 19 bool search (T element, T& foundElement) { … } 20 void makeEmpty() { … } 21 } 78
  • 79.
    Constructor, Destructor, IsEmpty() 1 BinarySearchTree() 2 : root(NULL) { } 3 4 ~BinarySearchTree() 5 { 6 makeEmpty(); 7 } 8 9 bool isEmpty() 10 { 11 return root == NULL: 12 } 79
  • 80.
    Printing Elements In Order 2 void inOrderTraversal() The client uses the 3 { driver called 4 inOrderInternal (root); InOrderTraversal. 5 } The recursive function inOrderInternal is called. inOrderInternal prints all element in BST in sorted order, starting from root node. 80
  • 81.
    Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { 5 inOrderInternal (parent->left); 6 cout << parent->info << " "; The base case 7 inOrderInternal (parent->right); occurs when 8 } parent is NULL – 9 } just returns. 81
  • 82.
    Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { There are 2 5 inOrderInternal (parent->left); recursive calls under the if – the 6 cout << parent->info << " "; first advances 7 inOrderInternal (parent->right); the pointer to the 8 } left child… 9 } and the second advances the pointer to the right child. 82
  • 83.
    Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { Each recursive 5 inOrderInternal (parent->left); call approaches 6 cout << parent->info << " "; the base case… 7 inOrderInternal (parent->right); it goes down one 8 } level through the 9 } tree, and it get closer to the case where parent->left or parent->right is NULL. 83
  • 84.
    Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { If the BST contains 4 if (parent != NULL) { only one node, the 5 inOrderInternal (parent->left); root node is the only 6 cout << parent->info << " "; node – the left and 7 inOrderInternal (parent->right); right pointers of the 8 } root node will be set 9 } to NULL. 84
  • 85.
    Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { parent->left is 5 inOrderInternal (parent->left); NULL, so NULL is passed into 6 cout << parent->info << " "; parent of the new 7 inOrderInternal (parent->right); inOrderInternal 8 } function. 9 } 85
  • 86.
    Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { Since parent is 4 if (parent != NULL) { NULL in the new 5 inOrderInternal (parent->left); inOrderInternal 6 cout << parent->info << " "; function, it will 7 inOrderInternal (parent->right); return right away. 8 } 9 } 86
  • 87.
    Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { parent->right is 5 inOrderInternal (parent->left); NULL – thus, 6 cout << parent->info << " "; the recursive 7 inOrderInternal (parent->right); function call immediately 8 } returns as 9 } before. 87
  • 88.
    Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { 5 inOrderInternal (parent->left); 6 cout << parent->info << " "; 7 inOrderInternal (parent->right); 8 } 9 } In fact inOrderInternal works correctly when there is only 0, 1 or many node in the BST. 88
  • 89.
    Printing Elements In Order (cont.) 2 void inOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { 5 inOrderInternal (parent->left); 6 cout << parent->info << " "; 7 inOrderInternal (parent->right); 8 } 9 } inOrderInternal is called once from the driver inOrderTraversal. Then, for each node in the tree, 2 calls to inOrderInternal are made, giving us a total of 2n + 1 calls where n is the number of nodes. 89
  • 90.
    Printing Elements Pre Order 2 void preOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { 5 cout << parent->info << " "; 6 preOrderInternal (parent->left); 7 preOrderInternal (parent->right); 8 } 9 } preOrderInternal prints the parent first. 90
  • 91.
    Printing Elements Post Order 2 void postOrderInternal (BSTNode<T> *parent) 3 { 4 if (parent != NULL) { 5 postOrderInternal (parent->left); 6 postOrderInternal (parent->right); 7 cout << parent->info << " "; 8 } 9 } postOrderInternal prints the parent last. 91
  • 92.
    Searching and Insertionin BST 1 bool search (T target, T& foundElement) { 2 return searchInternal (root, target, foundElement); 3 } 4 5 void insert (const T& newElement) { 6 insertInternal (root, newElement); 7 } 92
  • 93.
    Searching and Insertionin BST • We can actually figure out searchInternal and insertInternal using the same recursive logic as traversal in BST. 93
  • 94.
    References • Childs, J.S. (2008). Trees. C++ Classes and Data Structures. Prentice Hall. 94