1
Binary Trees
2
Definition and Applications of
Binary Trees
• A binary tree is a non-linear linked list
where each node may point to two other
nodes.
3
Definition and Applications of
Binary Trees
• It is anchored at the top by a tree pointer,
which is like the head pointer in a linked
list.
• The first node in the list is called the root
node.
• The root node has pointers to two other
nodes, which are called children, or child
nodes.
4
Definition and Applications of
Binary Trees
• A node that has no children is called a leaf
node.
• All pointers that do not point to a node are
set to NULL.
5
Definition and Applications of
Binary Trees
• Binary trees can be divided into subtrees. A
subtree is an entire branch of the tree, from
one particular node down.
6
Definition and Applications of
Binary Trees
• Binary trees are excellent data structures for
searching large amounts of information.
They are commonly used in database
applications to organize key values that
index database records.
• When used to facilitate searches, a binary
tree is called a binary search tree.
7
Definition and Applications of
Binary Trees
• Information is stored in binary search trees in a
way that makes a binary search simple. For
example, look at Figure 3.
Values are stored in a binary tree so
that a node's left child holds data
whose value is less than the node's
data, and the node's right child holds
data whose value is greater tan the
node's data.
8
Definition and Applications of
Binary Trees
• It is also true that all the nodes to the left of a node
hold values less than the node's value. Likewise,
all the nodes to the right of a node hold values that
are greater than the node's data.
• When an application is searching a binary tree, it
starts at the root node. If the root node does not
hold the search value, the application branches
either to the left or right child, depending on
whether the search value is less than or grater than
the value at the root node.
9
Definition and Applications of
Binary Trees
• This process continues until the value is found.
Figure 4 illustrates the search pattern for finding
the value P in the binary tree.
10
Binary Search Tree Operations
• Creating a Node: We will demonstrate binary tree
operations using the IntBinaryTree class.
• The basis of our binary tree node is the following
struct declaration:
struct TreeNode
{
int value;
TreeNode *left;
TreeNode *right;
};
• The struct is implemented in the class shown next…
11
IntBinaryTree.h
class IntBinaryTree
{
public:
struct TreeNode
{
int value;
TreeNode *left;
TreeNode *right;
};
TreeNode *root;
void destroySubTree(TreeNode *);
void deleteNode(int, TreeNode *&);
void makeDeletion(TreeNode *&);
void displayInOrder(TreeNode *);
void displayPreOrder(TreeNode *);
void displayPostOrder(TreeNode *);
12
IntBinaryTree.h
(continued)
public:
IntBinaryTree() // Constructor
{ root = NULL; }
~IntBinaryTree() // Destructor
{ destroySubTree(root); }
void insertNode(int);
bool searchNode(int);
void remove(int);
void showNodesInOrder(void)
{ displayInOrder(root); }
void showNodesPreOrder()
{ displayPreOrder(root); }
void showNodesPostOrder()
{ displayPostOrder(root); }
};
13
Binary Search Tree Operations
• Inserting a Node:First, a new node is allocated
and its value member is initialized with the new
value.
• The left and right child pointers are set to NULL,
because all nodes must be inserted as leaf nodes.
• Next, we determine if the tree is empty. If so, we
simply make root point to it, and there is nothing
else to be done. But, if there are nodes in the tree,
we must find the new node's proper insertion
point.
14
Binary Search Tree Operations
• If the new value is less than the root node's
value, we know it will be inserted somewhere in
the left subtree. Otherwise, the value will be
inserted into the right subtree.
• We simply traverse the subtree, comparing each
node along the way with the new node's value, and
deciding if we should continue to the left or the
right.
• When we reach a child pointer that is set to
NULL, we have found out insertion point.
15
The insertNode Member
Function
void IntBinaryTree::insertNode(int num)
{
TreeNode *newNode, // Pointer to a new node
*nodePtr; // Pointer to traverse the tree
// Create a new node
newNode = new TreeNode;
newNode->value = num;
newNode->left = newNode->right = NULL;
if (!root) // Is the tree empty?
root = newNode;
else
{
nodePtr = root;
16
The insertNode Member
Function
while (nodePtr != NULL)
{
if (num < nodePtr->value)
{
if (nodePtr->left)
nodePtr = nodePtr->left;
else
{
nodePtr->left = newNode;
break;
}
}
17
The insertNode Member
Function
else if (num > nodePtr->value)
{
if (nodePtr->right)
nodePtr = nodePtr->right;
else
{
nodePtr->right = newNode;
break;
}
}
else
{
cout << "Duplicate value found in tree.n";
break;
}
}
}
}
18
Program 1
// This program builds a binary tree with 5 nodes.
#include <iostream.h>
#include "IntBinaryTree.h“
void main(void)
{
IntBinaryTree tree;
cout << "Inserting nodes. ";
tree.insertNode(5);
tree.insertNode(8);
tree.insertNode(3);
tree.insertNode(12);
tree.insertNode(9);
cout << "Done.n";
}
19
Program 1
Figure 5 shows the structure of the binary tree built by the program.
Note: The shape of the tree is
determined by the order in
which the values are inserted.
The root node in the diagram
above holds the value 5 because
that was the first value inserted.
20
Traversing the Tree
• There are three common methods for
traversing a binary tree and processing the
value of each node:
– inorder
– preorder
– postorder
• Each of these methods is best implemented
as a recursive function.
21
Inorder Traversal
1. The node’s left subtree is traversed.
2. The node’s data is processed.
3. The node’s right subtree is traversed.
22
Preorder Traversal
1. The node’s data is processed.
2. The node’s left subtree is traversed.
3. The node’s right subtree is traversed.
23
Postorder Traversal
1. The node’s left subtree is traversed.
2. The node’s right subtree is traversed.
3. The node’s data is processed.
24
The displayInOrder
Member Function
void IntBinaryTree::displayInOrder(TreeNode *nodePtr)
{
if (nodePtr)
{
displayInOrder(nodePtr->left);
cout << nodePtr->value << endl;
displayInOrder(nodePtr->right);
}
}
25
The displayPreOrder
Member Function
void IntBinaryTree::displayPreOrder(TreeNode *nodePtr)
{
if (nodePtr)
{
cout << nodePtr->value << endl;
displayPreOrder(nodePtr->left);
displayPreOrder(nodePtr->right);
}
}
26
The displayPostOrder
Member Function
void IntBinaryTree::displayPostOrder(TreeNode *nodePtr)
{
if (nodePtr)
{
displayPostOrder(nodePtr->left);
displayPostOrder(nodePtr->right);
cout << nodePtr->value << endl;
}
}
27
Program 2
// This program builds a binary tree with 5 nodes.
// The nodes are displayed with inorder, preorder,
// and postorder algorithms.
#include <iostream.h>
#include "IntBinaryTree.h“
void main(void)
{
IntBinaryTree tree;
cout << "Inserting nodes.n";
tree.insertNode(5);
tree.insertNode(8);
tree.insertNode(3);
tree.insertNode(12);
tree.insertNode(9);
28
Program 2 (continued)
cout << "Inorder traversal:n";
tree.showNodesInOrder();
cout << "nPreorder traversal:n";
tree.showNodesPreOrder();
cout << "nPostorder traversal:n";
tree.showNodesPostOrder();
}
29
Program 2 (continued)
Program Output
Inserting nodes.
Inorder traversal:
3
5
8
9
12
Preorder traversal:
5
3
8
12
9
30
Program 2 (continued)
Postorder traversal:
3
9
12
8
5
31
Searching the Tree
The IntBinaryTree class has a public member function,
SearchNode, which returns true if a value is found in the tree, or
false otherwise.
bool IntBinaryTree::searchNode(int num)
{
TreeNode *nodePtr = root;
while (nodePtr)
{
if (nodePtr->value == num)
return true;
else if (num < nodePtr->value)
nodePtr = nodePtr->left;
else
nodePtr = nodePtr->right;
}
return false;
}
32
Program 3
// This program builds a binary tree with 5 nodes.
// The SearchNode function determines if the
// value 3 is in the tree.
#include <iostream.h>
#include "IntBinaryTree.h“
void main(void)
{
IntBinaryTree tree;
cout << "Inserting nodes.n";
tree.insertNode(5);
tree.insertNode(8);
tree.insertNode(3);
tree.insertNode(12);
tree.insertNode(9);
33
Program 3 (continued)
if (tree.searchNode(3))
cout << "3 is found in the tree.n";
else
cout << "3 was not found in the tree.n";
}
Program Output
Inserting nodes.
3 is found in the tree.
34
Deleting a Node
• We simply find its parent and set the child
pointer that links to it to NULL, and then
free the node's memory.
• But what if we want to delete a node that
has child nodes? We must delete the node
while at the same time preserving the
subtrees that the node links to.
35
Deleting a Node
• There are two possible situations when we
are deleting a non-leaf node:
– A) the node has one child, or
– B) the node has two children.
36
Deleting a Node
Figure 6 illustrates a tree in
which we are about to delete a
node with one subtree.
37
Deleting a Node
Figure 7 shows how we will link
the node's subtree with its
parent.
38
Deleting a Node
The problem is not as easily
solved, however, when the
node we are about to delete
has two subtrees. For example,
look at Figure 8.
39
Deleting a Node
• We cannot attach both of the node's subtrees
to its parent, so there must be an alternative
solution.
• One way is to attach the node's right subtree
to the parent, and then find a position in the
right subtree to attach the left subtree. The
result is shown in Figure 9.
40
Deleting a Node
Figure 9.
41
Deleting a Node
To delete a node from the IntBinaryTree, call the public member
function remove. The argument is the value of the node that is to be
deleted.
void IntBinaryTree::remove(int num)
{
deleteNode(num, root);
}
The remove member function calls the deleteNode member
function. It passes the value of the node to delete, and the root
pointer.
42
The deleteNode Member
Function
void IntBinaryTree::deleteNode(int num, TreeNode *&nodePtr)
{
if (num < nodePtr->value)
deleteNode(num, nodePtr->left);
else if (num > nodePtr->value)
deleteNode(num, nodePtr->right);
else
makeDeletion(nodePtr);
}
Notice the declaration of the nodePtr parameter:
TreeNode *&nodePtr;
nodePtr is not simply a pointer to a TreeNode structure, but a reference to a
pointer to a TreeNode structure. Any action performed on nodePtr is actually
performed on the argument passed into nodePtr.
43
The deleteNode Member
Function
else
makeDeletion(nodePtr);
•The trailing else statement calls the makeDeletion function,
passing nodePtr as its argument.
•The makeDeletion function actually deletes the node from the
tree, and must reattach the deleted node’s subtrees.
•Therefore, it must have access to the actual pointer in the binary tree
to the node that is being deleted.
•This is why the nodePtr parameter in the deleteNode function
is a reference.
44
The makeDeletion Member
Function
void IntBinaryTree::makeDeletion(TreeNode *&nodePtr)
{
TreeNode *tempNodePtr; // Temporary pointer, used in
// reattaching the left subtree.
if (nodePtr == NULL)
cout << "Cannot delete empty node.n";
else if (nodePtr->right == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->left; // Reattach the left child
delete tempNodePtr;
}
else if (nodePtr->left == NULL)
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->right; // Reattach the right child
delete tempNodePtr;
}
45
The makeDeletion Member
Function (continued)
// If the node has two children.
else
{
// Move one node the right.
tempNodePtr = nodePtr->right;
// Go to the end left node.
while (tempNodePtr->left)
tempNodePtr = tempNodePtr->left;
// Reattach the left subtree.
tempNodePtr->left = nodePtr->left;
tempNodePtr = nodePtr;
// Reattach the right subtree.
nodePtr = nodePtr->right;
delete tempNodePtr;
}
}
46
Program 4
// This program builds a binary tree with 5 nodes.
// The DeleteNode function is used to remove two
// of them.
#include <iostream.h>
#include "IntBinaryTree.h“
void main(void)
{
IntBinaryTree tree;
cout << "Inserting nodes.n";
tree.insertNode(5);
tree.insertNode(8);
tree.insertNode(3);
tree.insertNode(12);
tree.insertNode(9);
cout << "Here are the values in the tree:n";
tree.showNodesInOrder();
47
Program 4 (continued)
cout << "Deleting 8...n";
tree.remove(8);
cout << "Deleting 12...n";
tree.remove(12);
cout << "Now, here are the nodes:n";
tree.showNodesInOrder();
}
48
Program 4 (continued)
Program Output
Inserting nodes.
Here are the values in the tree:
3
5
8
9
12
Deleting 8...
Deleting 12...
Now, here are the nodes:
3
5
9
49
Template Considerations for
Binary Trees
• When designing your template, remember
that any data types stored in the binary tree
must support the <, >, and == operators.
• If you use the tree to store class objects,
these operators must be overridden.

Binary trees

  • 1.
  • 2.
    2 Definition and Applicationsof Binary Trees • A binary tree is a non-linear linked list where each node may point to two other nodes.
  • 3.
    3 Definition and Applicationsof Binary Trees • It is anchored at the top by a tree pointer, which is like the head pointer in a linked list. • The first node in the list is called the root node. • The root node has pointers to two other nodes, which are called children, or child nodes.
  • 4.
    4 Definition and Applicationsof Binary Trees • A node that has no children is called a leaf node. • All pointers that do not point to a node are set to NULL.
  • 5.
    5 Definition and Applicationsof Binary Trees • Binary trees can be divided into subtrees. A subtree is an entire branch of the tree, from one particular node down.
  • 6.
    6 Definition and Applicationsof Binary Trees • Binary trees are excellent data structures for searching large amounts of information. They are commonly used in database applications to organize key values that index database records. • When used to facilitate searches, a binary tree is called a binary search tree.
  • 7.
    7 Definition and Applicationsof Binary Trees • Information is stored in binary search trees in a way that makes a binary search simple. For example, look at Figure 3. Values are stored in a binary tree so that a node's left child holds data whose value is less than the node's data, and the node's right child holds data whose value is greater tan the node's data.
  • 8.
    8 Definition and Applicationsof Binary Trees • It is also true that all the nodes to the left of a node hold values less than the node's value. Likewise, all the nodes to the right of a node hold values that are greater than the node's data. • When an application is searching a binary tree, it starts at the root node. If the root node does not hold the search value, the application branches either to the left or right child, depending on whether the search value is less than or grater than the value at the root node.
  • 9.
    9 Definition and Applicationsof Binary Trees • This process continues until the value is found. Figure 4 illustrates the search pattern for finding the value P in the binary tree.
  • 10.
    10 Binary Search TreeOperations • Creating a Node: We will demonstrate binary tree operations using the IntBinaryTree class. • The basis of our binary tree node is the following struct declaration: struct TreeNode { int value; TreeNode *left; TreeNode *right; }; • The struct is implemented in the class shown next…
  • 11.
    11 IntBinaryTree.h class IntBinaryTree { public: struct TreeNode { intvalue; TreeNode *left; TreeNode *right; }; TreeNode *root; void destroySubTree(TreeNode *); void deleteNode(int, TreeNode *&); void makeDeletion(TreeNode *&); void displayInOrder(TreeNode *); void displayPreOrder(TreeNode *); void displayPostOrder(TreeNode *);
  • 12.
    12 IntBinaryTree.h (continued) public: IntBinaryTree() // Constructor {root = NULL; } ~IntBinaryTree() // Destructor { destroySubTree(root); } void insertNode(int); bool searchNode(int); void remove(int); void showNodesInOrder(void) { displayInOrder(root); } void showNodesPreOrder() { displayPreOrder(root); } void showNodesPostOrder() { displayPostOrder(root); } };
  • 13.
    13 Binary Search TreeOperations • Inserting a Node:First, a new node is allocated and its value member is initialized with the new value. • The left and right child pointers are set to NULL, because all nodes must be inserted as leaf nodes. • Next, we determine if the tree is empty. If so, we simply make root point to it, and there is nothing else to be done. But, if there are nodes in the tree, we must find the new node's proper insertion point.
  • 14.
    14 Binary Search TreeOperations • If the new value is less than the root node's value, we know it will be inserted somewhere in the left subtree. Otherwise, the value will be inserted into the right subtree. • We simply traverse the subtree, comparing each node along the way with the new node's value, and deciding if we should continue to the left or the right. • When we reach a child pointer that is set to NULL, we have found out insertion point.
  • 15.
    15 The insertNode Member Function voidIntBinaryTree::insertNode(int num) { TreeNode *newNode, // Pointer to a new node *nodePtr; // Pointer to traverse the tree // Create a new node newNode = new TreeNode; newNode->value = num; newNode->left = newNode->right = NULL; if (!root) // Is the tree empty? root = newNode; else { nodePtr = root;
  • 16.
    16 The insertNode Member Function while(nodePtr != NULL) { if (num < nodePtr->value) { if (nodePtr->left) nodePtr = nodePtr->left; else { nodePtr->left = newNode; break; } }
  • 17.
    17 The insertNode Member Function elseif (num > nodePtr->value) { if (nodePtr->right) nodePtr = nodePtr->right; else { nodePtr->right = newNode; break; } } else { cout << "Duplicate value found in tree.n"; break; } } } }
  • 18.
    18 Program 1 // Thisprogram builds a binary tree with 5 nodes. #include <iostream.h> #include "IntBinaryTree.h“ void main(void) { IntBinaryTree tree; cout << "Inserting nodes. "; tree.insertNode(5); tree.insertNode(8); tree.insertNode(3); tree.insertNode(12); tree.insertNode(9); cout << "Done.n"; }
  • 19.
    19 Program 1 Figure 5shows the structure of the binary tree built by the program. Note: The shape of the tree is determined by the order in which the values are inserted. The root node in the diagram above holds the value 5 because that was the first value inserted.
  • 20.
    20 Traversing the Tree •There are three common methods for traversing a binary tree and processing the value of each node: – inorder – preorder – postorder • Each of these methods is best implemented as a recursive function.
  • 21.
    21 Inorder Traversal 1. Thenode’s left subtree is traversed. 2. The node’s data is processed. 3. The node’s right subtree is traversed.
  • 22.
    22 Preorder Traversal 1. Thenode’s data is processed. 2. The node’s left subtree is traversed. 3. The node’s right subtree is traversed.
  • 23.
    23 Postorder Traversal 1. Thenode’s left subtree is traversed. 2. The node’s right subtree is traversed. 3. The node’s data is processed.
  • 24.
    24 The displayInOrder Member Function voidIntBinaryTree::displayInOrder(TreeNode *nodePtr) { if (nodePtr) { displayInOrder(nodePtr->left); cout << nodePtr->value << endl; displayInOrder(nodePtr->right); } }
  • 25.
    25 The displayPreOrder Member Function voidIntBinaryTree::displayPreOrder(TreeNode *nodePtr) { if (nodePtr) { cout << nodePtr->value << endl; displayPreOrder(nodePtr->left); displayPreOrder(nodePtr->right); } }
  • 26.
    26 The displayPostOrder Member Function voidIntBinaryTree::displayPostOrder(TreeNode *nodePtr) { if (nodePtr) { displayPostOrder(nodePtr->left); displayPostOrder(nodePtr->right); cout << nodePtr->value << endl; } }
  • 27.
    27 Program 2 // Thisprogram builds a binary tree with 5 nodes. // The nodes are displayed with inorder, preorder, // and postorder algorithms. #include <iostream.h> #include "IntBinaryTree.h“ void main(void) { IntBinaryTree tree; cout << "Inserting nodes.n"; tree.insertNode(5); tree.insertNode(8); tree.insertNode(3); tree.insertNode(12); tree.insertNode(9);
  • 28.
    28 Program 2 (continued) cout<< "Inorder traversal:n"; tree.showNodesInOrder(); cout << "nPreorder traversal:n"; tree.showNodesPreOrder(); cout << "nPostorder traversal:n"; tree.showNodesPostOrder(); }
  • 29.
    29 Program 2 (continued) ProgramOutput Inserting nodes. Inorder traversal: 3 5 8 9 12 Preorder traversal: 5 3 8 12 9
  • 30.
  • 31.
    31 Searching the Tree TheIntBinaryTree class has a public member function, SearchNode, which returns true if a value is found in the tree, or false otherwise. bool IntBinaryTree::searchNode(int num) { TreeNode *nodePtr = root; while (nodePtr) { if (nodePtr->value == num) return true; else if (num < nodePtr->value) nodePtr = nodePtr->left; else nodePtr = nodePtr->right; } return false; }
  • 32.
    32 Program 3 // Thisprogram builds a binary tree with 5 nodes. // The SearchNode function determines if the // value 3 is in the tree. #include <iostream.h> #include "IntBinaryTree.h“ void main(void) { IntBinaryTree tree; cout << "Inserting nodes.n"; tree.insertNode(5); tree.insertNode(8); tree.insertNode(3); tree.insertNode(12); tree.insertNode(9);
  • 33.
    33 Program 3 (continued) if(tree.searchNode(3)) cout << "3 is found in the tree.n"; else cout << "3 was not found in the tree.n"; } Program Output Inserting nodes. 3 is found in the tree.
  • 34.
    34 Deleting a Node •We simply find its parent and set the child pointer that links to it to NULL, and then free the node's memory. • But what if we want to delete a node that has child nodes? We must delete the node while at the same time preserving the subtrees that the node links to.
  • 35.
    35 Deleting a Node •There are two possible situations when we are deleting a non-leaf node: – A) the node has one child, or – B) the node has two children.
  • 36.
    36 Deleting a Node Figure6 illustrates a tree in which we are about to delete a node with one subtree.
  • 37.
    37 Deleting a Node Figure7 shows how we will link the node's subtree with its parent.
  • 38.
    38 Deleting a Node Theproblem is not as easily solved, however, when the node we are about to delete has two subtrees. For example, look at Figure 8.
  • 39.
    39 Deleting a Node •We cannot attach both of the node's subtrees to its parent, so there must be an alternative solution. • One way is to attach the node's right subtree to the parent, and then find a position in the right subtree to attach the left subtree. The result is shown in Figure 9.
  • 40.
  • 41.
    41 Deleting a Node Todelete a node from the IntBinaryTree, call the public member function remove. The argument is the value of the node that is to be deleted. void IntBinaryTree::remove(int num) { deleteNode(num, root); } The remove member function calls the deleteNode member function. It passes the value of the node to delete, and the root pointer.
  • 42.
    42 The deleteNode Member Function voidIntBinaryTree::deleteNode(int num, TreeNode *&nodePtr) { if (num < nodePtr->value) deleteNode(num, nodePtr->left); else if (num > nodePtr->value) deleteNode(num, nodePtr->right); else makeDeletion(nodePtr); } Notice the declaration of the nodePtr parameter: TreeNode *&nodePtr; nodePtr is not simply a pointer to a TreeNode structure, but a reference to a pointer to a TreeNode structure. Any action performed on nodePtr is actually performed on the argument passed into nodePtr.
  • 43.
    43 The deleteNode Member Function else makeDeletion(nodePtr); •Thetrailing else statement calls the makeDeletion function, passing nodePtr as its argument. •The makeDeletion function actually deletes the node from the tree, and must reattach the deleted node’s subtrees. •Therefore, it must have access to the actual pointer in the binary tree to the node that is being deleted. •This is why the nodePtr parameter in the deleteNode function is a reference.
  • 44.
    44 The makeDeletion Member Function voidIntBinaryTree::makeDeletion(TreeNode *&nodePtr) { TreeNode *tempNodePtr; // Temporary pointer, used in // reattaching the left subtree. if (nodePtr == NULL) cout << "Cannot delete empty node.n"; else if (nodePtr->right == NULL) { tempNodePtr = nodePtr; nodePtr = nodePtr->left; // Reattach the left child delete tempNodePtr; } else if (nodePtr->left == NULL) { tempNodePtr = nodePtr; nodePtr = nodePtr->right; // Reattach the right child delete tempNodePtr; }
  • 45.
    45 The makeDeletion Member Function(continued) // If the node has two children. else { // Move one node the right. tempNodePtr = nodePtr->right; // Go to the end left node. while (tempNodePtr->left) tempNodePtr = tempNodePtr->left; // Reattach the left subtree. tempNodePtr->left = nodePtr->left; tempNodePtr = nodePtr; // Reattach the right subtree. nodePtr = nodePtr->right; delete tempNodePtr; } }
  • 46.
    46 Program 4 // Thisprogram builds a binary tree with 5 nodes. // The DeleteNode function is used to remove two // of them. #include <iostream.h> #include "IntBinaryTree.h“ void main(void) { IntBinaryTree tree; cout << "Inserting nodes.n"; tree.insertNode(5); tree.insertNode(8); tree.insertNode(3); tree.insertNode(12); tree.insertNode(9); cout << "Here are the values in the tree:n"; tree.showNodesInOrder();
  • 47.
    47 Program 4 (continued) cout<< "Deleting 8...n"; tree.remove(8); cout << "Deleting 12...n"; tree.remove(12); cout << "Now, here are the nodes:n"; tree.showNodesInOrder(); }
  • 48.
    48 Program 4 (continued) ProgramOutput Inserting nodes. Here are the values in the tree: 3 5 8 9 12 Deleting 8... Deleting 12... Now, here are the nodes: 3 5 9
  • 49.
    49 Template Considerations for BinaryTrees • When designing your template, remember that any data types stored in the binary tree must support the <, >, and == operators. • If you use the tree to store class objects, these operators must be overridden.