Data Structures
Data Structures
DATA STRUCTURES
Lecture 7:
Tree, Binary Trees and Binary Search Trees
What is a Tree?
• T is a tree if either
– T has no nodes, or
– T is of the form:
2
Tree Terminology
Parent – The parent of node n is the node directly above in the tree.
Child – The child of node n is the node directly below in the tree.
• If node m is the parent of node n, node n is the child of node m.
Root – The only node in the tree with no parent.
3
A Tree – Example
Root A
B C D E F G
Leaf
H I J K L M N
Siblings
P Q
4
What is a Tree?
5
Level of a node
Level – The level of node n is the number of nodes on the path from root
to node n.
6
Level of a node
Level – The level of node n is the number of nodes on the path from root
to node n.
Level 2
Level 3
Level 4
7
Height of A Tree
Height – number of nodes on longest path from the root to any leaf.
• The height of a tree T in terms of the levels of its nodes is defined as:
– If T is empty, its height is 0
– If T is not empty, its height is equal to the maximum level of its nodes.
height(T) = 1 + max{height(T1),height(T2),...,height(Tk)}
8
Binary Tree
• A binary tree T is a set of nodes with the following properties:
– The set can be empty.
– Otherwise, the set is partitioned into three disjoint subsets:
• a tree consists of a distinguished node r, called root, and
• two possibly empty sets are binary tree, called left and right subtrees of
r.
9
Binary Tree Terminology
Left Child – The left child of node n is a node directly below and to the left
of node n in a binary tree.
Right Child – The right child of node n is a node directly below and to the
right of node n in a binary tree.
Left Subtree – In a binary tree, the left subtree of node n is the left child
(if any) of node n plus its descendants.
Right Subtree – In a binary tree, the right subtree of node n is the right
child (if any) of node n plus its descendants.
10
Binary Tree -- Example
• A is the root.
•A
•C • B is left child of A,
•B
C is right child of A.
•D •E
• D doesn’t have a right child.
•F •G •H
• H doesn’t have a left child.
•I
• B, F, G and I are leaves.
11
Binary Tree – Representing Algebraic Expressions
12
Height of Binary Tree
• The height of a binary tree T can be defined as recursively as:
– If T is empty, its height is 0.
– If T is non-empty tree, then since T is of the form ...
... height of T is 1 greater than height of its root’s taller subtree; ie.
height(T) = 1 + max{height(TL),height(TR)}
13
Height of Binary Tree (cont.)
14
Number of Structurally Different Binary trees with n Nodes
n=1
• (1 tree)
• •
n=2 (2 trees)
• •
• • • • •
n=3
• • • • • • (5 trees)
• • • •
To express, structurally different binary trees with n nodes:
Let us arbitrarily order the elements in the tree from 1, 2 … , n, and assume that only the lower order nodes can be placed
as the left child to the root node and higher order nodes as the right child.
15
Number of Structurally Different Binary trees with n Nodes
To express, structurally different binary trees with n nodes:
Let us arbitrarily order the elements in the tree from 1, 2 … , n, and assume that only the lower order nodes can be placed
as the left child to the root node and higher order nodes as the right child.
16
Number of Structurally Different Binary trees with n Nodes
To express, structurally different binary trees with n nodes:
Let us arbitrarily order the elements in the tree from 1, 2 … , n, and assume that only the lower order nodes can be placed
as the left child to the root node and higher order nodes as the right child.
All subtrees are also binary trees. So, the number of binary trees can be computed using a recursive function f(n), where the base cases
f(0)=1 (only one way to generate empty binary tree) and f(1)=1 (1 way to generate a BT with one node) as follows:
𝑛
𝑓(𝑛) = ∑ 𝑓(𝑖 − 1)𝑓(𝑛 − 𝑖)
𝑖=1
f(0) = 1
f(1) = 1
f(2) = 2
f(3) = 5
f(4) = ?
17
Number of Structurally Different Binary trees with n Nodes
n=0 empty tree (1 tree)
n=1
• (1 tree)
• •
n=2 (2 trees)
• •
• • • • •
n=3
• • • • • • (5 trees)
• • • •
n is even
n is odd
18
Full Binary Tree
• In a full binary tree of height h, all nodes that are at a level less than h
have two children each.
• Each node in a full binary tree has left and right subtrees of the same
height.
• Among binary trees of height h, a full binary tree has as many leaves as
possible, and all the leaves are at level h.
• A full binary tree has no missing nodes.
• Recursive definition of full binary tree:
– If T is empty, T is a full binary tree of height 0.
– If T is not empty and has height h>0, T is a full binary tree if its root’s
subtrees are both full binary trees of height h-1.
19
Full Binary Tree – Example
20
Complete Binary Tree
• A complete binary tree of height h is a binary tree that is full down to
level h-1, with level h filled in from left to right.
21
Complete Binary Tree – Example
22
Balanced Binary Tree
23
Maximum and Minimum Heights of a Binary Tree
• Efficiency of most binary tree operations depends on tree height.
• Each level of a minimum height tree, except the last level, must contain
as many nodes as possible.
– Should the tree be a Complete Binary Tree?
24
Maximum and Minimum Heights of a Binary Tree
25
Counting the nodes in a full binary tree of height h
26
Some Height Theorems
Theorem: A full binary tree of height h0 has 2h-1 nodes.
• The maximum number of nodes that a binary tree of height h can have
is 2h-1.
27
Some Height Theorems
Theorem 10-4: The minimum height of a binary tree with n nodes is log2(n+1) .
Proof: Let h be the smallest integer such that n2h-1. We can establish following facts:
Fact 1 – A binary tree whose height is h-1 has < n nodes.
– Otherwise h cannot be smallest integer in our assumption.
Fact 2 – There exists a complete binary tree of height h that has exactly n nodes.
– A full binary tree of height h-1 has 2h-1-1 nodes.
– Since a binary tree of height h cannot have more than 2h-1 nodes.
– At level h, we will reach n nodes.
Fact 3 – The minimum height of a binary tree with n nodes is the smallest integer h
such that n 2h-1.
So, ➔ 2h-1-1 < n 2h-1
➔ 2h-1 < n+1 2h
➔ h-1 < log2(n+1) h
Thus, ➔ h = log2(n+1) is the minimum height of a binary tree with n nodes.
28
• UML Diagram for BinaryTree ADT
• What is an ADT?
29
An Array-Based Implementation of Binary Trees
const int MAX_NODES = 100; // maximum number of nodes
typedef string TreeItemType;
class TreeNode { // node in the tree
private:
TreeNode();
TreeNode(const TreeItemType& nodeItem, int left, int right);
31
An Array-Based Representation of
a Complete Binary Tree
• If we know that our binary tree is a complete binary tree, we can use a simpler
array-based representation for complete binary trees
• without using leftChild, rightChild links
• We can number the nodes level by level, and left to right (starting from 0, the root
will be 0). If a node is numbered as i, in the ith location of the array, tree[i],
contains this node without links.
• Using these numbers we can find leftChild, rightChild, and parent of a node i.
32
An Array-Based Representation of a Complete Binary Tree
(cont.)
1 2
3 4 5
33
Pointer-Based Implementation of Binary Trees
34
A Pointer-Based Implementation of
a Binary Tree Node
typedef string TreeItemType;
35
Binary Tree – TreeException.h
class TreeException : public exception{
private:
string msg;
public:
virtual const char* what() const throw()
{
return msg.c_str();
}
TreeException(const string & message =""):
exception(), msg(message) {};
~TreeException() throw() {};
}; // end TreeException
36
37
The BinaryTree Class
• Properties
– TreeNode * root
• Constructors
– BinaryTree();
– BinaryTree(const TreeItemType& rootItem);
– BinaryTree(const TreeItemType& rootItem,
BinaryTree& leftTree, BinaryTree& rightTree);
– BinaryTree(const BinaryTree& tree);
void copyTree(TreeNode *treePtr, TreeNode* & newTreePtr) const;
• Destructor
– ~BinaryTree();
void destroyTree(TreeNode * &treePtr);
38
BinaryTree: Public Methods
• bool isEmpty()
• TreeItemType rootData() const throw(TreeException)
• void setRootData(const TreeItemType& newItem)
• void attachLeft(const TreeItemType& newItem)
• void attachRight(const TreeItemType& newItem)
• void attachLeftSubtree(BinaryTree& leftTree)
• void attachRightSubtree(BinaryTree& rightTree)
• void detachLeftSubtree(BinaryTree& leftTree)
• void detachRightSubtree(BinaryTree& rightTree)
• BinaryTree leftSubtree()
• BinaryTree rightSubtree()
• void preorderTraverse(FunctionType visit_fn)
• void inorderTraverse(FunctionType visit_fn)
• void postorderTraverse(FunctionType visit_fn)
• FunctionType is a pointer to a function:
• typedef void (*FunctionType)(TreeItemType& anItem);
39
BinaryTree: Implementation
• The complete implementation is in
– Frank M. Carrano and Timothy Henry, Data Abstraction and Problem Solving with
C++: Walls and Mirrors, 7th edition, Pearson, 2017
40
// Default constructor
BinaryTree::BinaryTree() : root(NULL) {
// Protected constructor
BinaryTree::BinaryTree(TreeNode *nodePtr) : root(nodePtr) {
// Constructor
BinaryTree::BinaryTree(const TreeItemType& rootItem) {
root = new TreeNode(rootItem, NULL, NULL);
}
41
// Constructor
BinaryTree::BinaryTree(const TreeItemType& rootItem,
BinaryTree& leftTree, BinaryTree& rightTree) {
root = new TreeNode(rootItem, NULL, NULL);
attachLeftSubtree(leftTree);
attachRightSubtree(rightTree);
}
42
// Copy constructor
BinaryTree::BinaryTree(const BinaryTree& tree) {
copyTree(tree.root, root);
}
43
// Destructor
BinaryTree::~BinaryTree() {
destroyTree(root);
}
if (treePtr != NULL){
destroyTree(treePtr->leftChildPtr);
destroyTree(treePtr->rightChildPtr);
delete treePtr;
treePtr = NULL;
}
}
44
Binary Tree Traversals
• Preorder Traversal
– The node is visited before its left and right subtrees,
– Visit the node, visit the left subtree, visit the right subtree
• Postorder Traversal
– The node is visited after both subtrees.
– Visit the left subtree, visit the right subtree, visit the node
• Inorder Traversal
– The node is visited between the subtrees,
– Visit the left subtree, visit the node, and visit the right subtree.
45
Binary Tree Traversals
46
void BinaryTree::preorderTraverse(FunctionType visit) {
preorder(root, visit);
}
void BinaryTree::inorderTraverse(FunctionType visit) {
inorder(root, visit);
}
void BinaryTree::postorderTraverse(FunctionType visit) {
postorder(root, visit);
}
---------------------------------------------------------------------------------------------------------
Remember that:
FunctionType is a pointer to a function
• Variables that point to the address of a function
• typedef void (*FunctionType)(TreeItemType& anItem);
47
void BinaryTree::preorder(TreeNode *treePtr, FunctionType visit) {
if (treePtr != NULL) {
visit(treePtr->item);
preorder(treePtr->leftChildPtr, visit);
preorder(treePtr->rightChildPtr, visit);
}
}
48
Complexity of Traversals
What is the complexity of each traversal type?
• Preorder traversal
• Postorder traversal
• Inorder traversal
49
Binary Search Tree
• An important application of binary trees is their use in searching.
• Binary search tree is a binary tree in which every node X contains a data
value that satisfies the following:
a) all data values in its left subtree are smaller than data value in X
b) all data values in its right subtree are larger than data value in X
c) the left and right subtrees are also binary search trees
50
Binary Search Tree
6 6
2 8 2 8
1 4 1 4
3 3 7
51
Binary Search Trees – containing same data
52
BinarySearchTree Class – UML Diagram
53
The KeyedItem Class
typedef desired-type-of-search-key KeyType;
class KeyedItem {
public:
KeyedItem() { }
KeyedItem(const KeyType& keyValue) : searchKey(keyValue) { }
private:
KeyType searchKey;
// ... and other data items
};
54
The TreeNode Class
typedef KeyedItem TreeItemType;
55
The BinarySearchTree Class
• Properties
– TreeNode * root
• Constructors
– BinarySearchTree();
– BinarySearchTree(const BinarySearchTree& tree);
• Destructor
– ~BinarySearchTree();
56
The BinarySearchTree Class
• Public methods
57
The BinarySearchTree Class
• Protected methods
58
Searching (Retrieving) an Item in a BST
void BinarySearchTree::searchTreeRetrieve(KeyType searchKey,
TreeItemType& treeItem) const throw(TreeException) {
retrieveItem(root, searchKey, treeItem);
}
if (treePtr == NULL)
throw TreeException("TreeException: searchKey not found");
else if (searchKey == treePtr->item.getKey())
treeItem = treePtr->item;
else if (searchKey < treePtr->item.getKey())
retrieveItem(treePtr->leftChildPtr, searchKey, treeItem);
else
retrieveItem(treePtr->rightChildPtr, searchKey, treeItem);
}
59
Inserting an Item into a BST
Insert 5
2 8
1 4
3 5
60
Inserting an Item into a BST
void BinarySearchTree::searchTreeInsert(const TreeItemType& newItem) {
insertItem(root, newItem);
}
61
Inserting an Item into a BST
62
Deleting An Item from a BST
• To delete an item from a BST, we have to locate that item in that BST.
63
Deletion – Case 1: A Leaf Node
To remove the leaf containing the item, we have to set the pointer in its parent to NULL.
50 50
➔
40 60 40 60
30 45 70
30 45
42
42
64
Deletion – Case 2: A Node with only a left child
50
50
➔ 40 60
40 60
30 42 70
30 45 70
42
65
Deletion – Case 2: A Node with only a right child
50
50
➔ 40 70
40 60
30 45
30 45 70
42
42
66
Deletion – Case 3: A Node with two children
• Locate the inorder successor of the node.
• Copy the item in this node into the node which contains the item which will be deleted.
50 50
➔ 42 60
40 60
70 30 45 70
30 45
42
67
Deletion – Case 3: A Node with two children
68
Deletion – Case 3: A Node with two children
Delete 2
69
Deletion from a BST
void BinarySearchTree::searchTreeDelete(KeyType searchKey) throw(TreeException) {
deleteItem(root, searchKey);
}
70
Deletion from a BST
void BinarySearchTree::deleteNodeItem(TreeNode * &nodePtr) {
TreeNode *delPtr;
TreeItemType replacementItem;
71
Deletion from a BST
72
Deletion from a BST
if (nodePtr->leftChildPtr == NULL) {
treeItem = nodePtr->item;
TreeNode *delPtr = nodePtr;
nodePtr = nodePtr->rightChildPtr;
delPtr->rightChildPtr = NULL; // defense
delete delPtr;
}
else
processLeftmost(nodePtr->leftChildPtr, treeItem);
}
73
Traversals
• The traversals for binary search trees are same as
the traversals for the binary trees.
74
Minimum Height
• Complete trees and full trees have minimum height.
• The height of an n-node binary search tree ranges
from log2(n+1) to n.
75
Average Height
• If we insert n items into an empty BST to create a BST with n nodes,
– How many different binary search trees with n nodes?
– What are their probabilities?
77
Saving a BST into a file and
restoring it to its original shape
• Save:
– Use a preorder traversal to save the nodes of the BST into a file
• Restore:
– Start with an empty BST
– Read the nodes from the file one by one and insert them
into the BST
78
Saving a BST into a file and
restoring it to its original shape
Preorder: 60 20 10 40 30 50 70
79
Saving a BST into a file and
restoring it to a minimum-height BST
• Save:
– Use an inorder traversal to save the nodes of the BST into a file. The
saved nodes will be in ascending order
– Save the number of nodes (n) in somewhere
• Restore:
– Read the number of nodes (n)
– Start with an empty BST
– Read the nodes from the file one by one to create a minimum-
height binary search tree
80
Building a minimum-height BST
// Builds a minimum-height binary search tree from n sorted
// values in a file. treePtr will point to the tree’s root.
readTree(out treePtr:TreeNodePtr, in n:integer)
if (n>0) {
treePtr = pointer to new node with NULL child pointers
81
A full tree saved in a file by using inorder traversal
82
A General Tree
83
A Pointer-Based Implementation of General Trees
84
A Pointer-Based Implementation of General Trees
A pointer-based implementation of
a general tree can also represent
a binary tree.
85
N-ary Tree
An n-ary tree is a generalization of a binary whose
nodes each can have no more than n children.
86