49
Starting Out with C++, 3 rd Edition 1 Binary Binary Trees Trees

Starting Out with C++, 3 rd Edition 1 Binary Trees

Embed Size (px)

Citation preview

Page 1: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

1

Binary TreesBinary Trees

Page 2: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

2

11. Definition and Applications of Definition and Applications of Binary TreesBinary Trees

• A binary tree is a non-linear linked list where each node may point to two other nodes.

Page 3: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

3

• 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 nodenode..

• The root node has pointers to two other nodes, which are called children, or child nodes.

Page 4: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

4

• A node that has no children is called a leaf node.

• All pointers that do not point to a node are set to NULL.

Page 5: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

5

• Binary trees can be divided into subtrees. A subtree is an entire branch of the tree, from one particular node down.

Page 6: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

6

• 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.

Page 7: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

7

• 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.

Page 8: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

8

• 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.

Page 9: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

9

• This process continues until the value is found. Figure-4 illustrates the search pattern for finding the value P in the binary tree.

Page 10: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

10

2. Binary Search Tree 2. Binary Search Tree OperationsOperations

• 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…

Page 11: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

11

IntBinaryTree.hclass 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 *);

Page 12: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

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); }};

Page 13: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

13

2. Binary Search Tree 2. Binary Search Tree OperationsOperations

• Inserting a Node:First, a new node is allocated and its valuevalue 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.

Page 14: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

14

2. 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.

Page 15: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

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 nodenewNode = new TreeNode;newNode->value = num;newNode->left = newNode->right = NULL;

if (!root) // Is the tree empty?root = newNode;

else{

nodePtr = root;

Page 16: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

16

The insertNode Member Function

while (nodePtr != NULL){

if (num < nodePtr->value){

if (nodePtr->left)nodePtr = nodePtr->left;

else{

nodePtr->left = newNode;break;

}}

Page 17: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

17

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;

}}

}}

Page 18: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

18

Program -1Program -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";

}

Page 19: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

19

Program -1Figure 20-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.

Page 20: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

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.

Page 21: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

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.

Page 22: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

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.

Page 23: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

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.

Page 24: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

24

The displayInOrder Member Function

void IntBinaryTree::displayInOrder(TreeNode *nodePtr){

if (nodePtr){

displayInOrder(nodePtr->left);cout << nodePtr->value << endl;displayInOrder(nodePtr->right);

}}

Page 25: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

25

The displayPreOrder Member Function

void IntBinaryTree::displayPreOrder(TreeNode *nodePtr){

if (nodePtr){

cout << nodePtr->value << endl;displayPreOrder(nodePtr->left);displayPreOrder(nodePtr->right);

}}

Page 26: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

26

The displayPostOrder Member Function

void IntBinaryTree::displayPostOrder(TreeNode *nodePtr){

if (nodePtr){

displayPostOrder(nodePtr->left);displayPostOrder(nodePtr->right);cout << nodePtr->value << endl;

}}

Page 27: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

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);

Page 28: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

28

Program -2 (continued)cout << "Inorder traversal:\n";tree.showNodesInOrder();cout << "\nPreorder traversal:\n";tree.showNodesPreOrder();cout << "\nPostorder traversal:\n";tree.showNodesPostOrder();

}

Page 29: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

29

Program -2 (continued)Program Output 

Inserting nodes.Inorder traversal:358912 Preorder traversal:538129

Page 30: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

30

Program -2 (continued)Postorder traversal:3

91285

Page 31: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

31

Searching the TreeSearching 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;

elsenodePtr = nodePtr->right;

}return false;

}

Page 32: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

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);

Page 33: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

33

Program -3 (continued)

if (tree.searchNode(3))cout << "3 is found in the tree.\n";

elsecout << "3 was not found in the tree.\n";

}

Program Output Inserting nodes.3 is found in the tree.

Page 34: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

34

Deleting a NodeDeleting 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.

Page 35: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

35

Deleting a NodeDeleting 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.

Page 36: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

36

Figure 20-6 illustrates a tree in which we are about to delete a node with one subtree.

Page 37: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

37

Figure -7 shows how we will link the node's subtree with its parent.

Page 38: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

38

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.

Page 39: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

39

• 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.

Page 40: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

40Figure -9.

Page 41: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

41

Deleting a NodeDeleting 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.

Page 42: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

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);

elsemakeDeletion(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.

Page 43: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

43

The deleteNode Member Function

elsemakeDeletion(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.

Page 44: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

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 childdelete tempNodePtr;

}else if (nodePtr->left == NULL){

tempNodePtr = nodePtr;nodePtr = nodePtr->right; // Reattach the right childdelete tempNodePtr;

}

Page 45: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

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;

}}

Page 46: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

46

Program 20-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();

Page 47: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

47

Program 20-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();

}

Page 48: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

48

Program 20-4 (continued)

Program Output

 Inserting nodes.Here are the values in the tree:358912Deleting 8...Deleting 12...Now, here are the nodes:359

Page 49: Starting Out with C++, 3 rd Edition 1 Binary Trees

Starting Out with C++, 3rd Edition

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.