L3 Trees
L3 Trees
Initially prepared by Dr. İlyas Çiçekli; improved by various Bilkent CS202 instructors.
• T is a tree if either
– T has no nodes, or
– T is of the form:
Subtree – A subtree of node n is a tree that consists of a child (if any) of n and the
child’s descendants (a tree which is rooted by a child of node n)
B C D E F G
Leaf
H I J K L M N
Siblings
P Q
height(T) = 1 + max{height(T1),height(T2),...,height(Tk)}
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.
• 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.
... height of T is 1 greater than height of its root’s taller subtree; ie.
height(T) = 1 + max{height(TL),height(TR)}
n=1 🡺
∙ (1 tree)
∙ ∙
n=2 🡺 (2 trees)
∙ ∙
∙ ∙ ∙ ∙ ∙
n=3 🡺 (5 trees)
∙ ∙ ∙ ∙ ∙ ∙
∙ ∙ ∙ ∙
n is even 🡺
n is odd 🡺
CS202 - Fundamentals of Computer Science II 14
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 leaves all 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.
• 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?
• The maximum number of nodes that a binary tree of height h can have
is 2h-1.
• What is an ADT?
• 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.
1 2
3 4 5
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
• 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);
// Protected constructor
BinaryTree::BinaryTree(TreeNode *nodePtr) : root(nodePtr) {
// Constructor
BinaryTree::BinaryTree(const TreeItemType& rootItem) {
root = new TreeNode(rootItem, NULL, NULL);
}
if (treePtr != NULL){
destroyTree(treePtr->leftChildPtr);
destroyTree(treePtr->rightChildPtr);
delete treePtr;
treePtr = NULL;
}
}
• Postorder Traversal
– The node is visited after both subtrees.
• Inorder Traversal
– The node is visited between the subtrees,
– Visit left subtree, visit the node, and visit the right subtree.
• Preorder traversal
• Postorder traversal
• Inorder traversal
2 8 2 8
1 4 1 4
3 3 7
class KeyedItem {
public:
KeyedItem() { }
KeyedItem(const KeyType& keyValue) : searchKey(keyValue) { }
private:
KeyType searchKey;
// ... and other data items
};
• Constructors
– BinarySearchTree();
– BinarySearchTree(const BinarySearchTree& tree);
• Destructor
– ~BinarySearchTree();
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);
}
Insert 5
2 8
1 4
3 5
50 50
40 60
🡺
40 60
30 45 70
30 45
42
42
50
50
40 60
🡺 40 60
30 42 70
30 45 70
42
50
50
🡺 40 70
40 60
30 45
30 45 70
42
42
• Copy the item in this node into the node which contains the item which will be deleted.
50 50
40 60 🡺 42 60
70 30 45 70
30 45
42
Delete 2
if (nodePtr->leftChildPtr == NULL) {
treeItem = nodePtr->item;
TreeNode *delPtr = nodePtr;
nodePtr = nodePtr->rightChildPtr;
delPtr->rightChildPtr = NULL; // defense
delete delPtr;
}
else
processLeftmost(nodePtr->leftChildPtr, treeItem);
}
Traverse bTree in inorder. As you visit bTree’s nodes, copy their data items into
successive locations of anArray
• Restore:
– Start with an empty BST
– Read the nodes from the file one by one and insert them
into the BST
Preorder: 60 20 10 40 30 50 70
• 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
if (n>0) {
treePtr = pointer to new node with NULL child pointers
A pointer-based implementation of
a general tree can also represent
a binary tree.