Transcript Chapter 8

Binary Search Trees
CISC2200, Fall 09
1
Trees
Owner
Jake
Manager
Brad
Waitress
Joyce
Chef
Carol
Waiter
Chris
Jake’s Pizza Shop
2
Cook
Max
Helper
Len
Trees
ROOT NODE
Owner
Jake
Manager
Brad
Waitress
Joyce
3
Chef
Carol
Waiter
Chris
Cook
Max
Helper
Len
Trees
Owner
Jake
Manager
Brad
Waitress
Joyce
LEAF NODES
4
Chef
Carol
Waiter
Chris
Cook
Max
Helper
Len
Trees
Owner
Jake
LEVEL 0
Manager
Brad
Waitress
Joyce
5
Chef
Carol
Waiter
Chris
Cook
Max
Helper
Len
Trees
Owner
Jake
Manager
Brad
LEVEL 1
Waitress
Joyce
6
Chef
Carol
Waiter
Chris
Cook
Max
Helper
Len
Trees
Owner
Jake
Manager
Brad
Chef
Carol
LEVEL 2
Waitress
Joyce
7
Waiter
Chris
Cook
Max
Helper
Len
Trees
Owner
Jake
Manager
Brad
Waitress
Joyce
Chef
Carol
Waiter
Chris
LEFT SUBTREE OF ROOT NODE
8
Cook
Max
Helper
Len
Trees
Owner
Jake
Manager
Brad
Waitress
Joyce
Chef
Carol
Waiter
Chris
Cook
Max
Helper
Len
RIGHT SUBTREE
OF ROOT NODE
9
Binary Trees
A structure with i) a unique starting node (the
root), in which ii) each node has up to two child
nodes and iii) a unique path exists from the
root to every other node
Root
top node of a tree structure; a node with no
parent
Leaf Node
A tree node that has no children
10
Trees: level and height
• Level: distance of a node from the root
• Height: the maximum level
11
Trees
Why is this not a
tree?
A tree is a structure with i) a unique starting node (the
root), in which ii) each node is capable of having two
child nodes and iii) a unique path exists from the root
to every other node
12
Descendants
Descendant of a node is a child
of the node, and any child of the
children, etc.
V
Q
L
T
E
K
How many descendants does Q have?
13
A
S
Ancestors
Ancestor of a node:
a parent of the node,
the parent of the
parent, etc.
V
Q
L
T
E
K
How many ancestors does S have?
14
A
S
Many different shapes of Binary Trees
How many different shape binary trees can be made
from 2 nodes? 4 nodes? 6 nodes?
15
Facts of Binary Tree

Max. number of nodes at Nth level : 2N.




0th level: root node: 1
1th level: 2
Double as level increases by 1
Suppose f(n) denote the maximum number of
nodes at nth level:


f(0)=1
f(n)=2*f(n-1) for n>=1
A recursive formula!
 f(n)=2n

16
Facts of Binary Tree

Max. total number of nodes in a tree of height N


17
All levels are full, so add the max. number of nodes at
each level together:
20+21+22+…+2N= 2N+1-1
Facts of Binary Tree

Given a binary tree with N node, what is the
min. number of levels?

Try to fill in each level
The answer is: log2N +1
 Max. number of levels with N nodes ?



18
One node at each level => degenerate to a linked list
The answer is: N
Binary Search Trees (BST)
A BST is a binary tree with search property
A binary tree in which, for each node
• key value in the node is greater than the key value in
its left child and any of the left child’s descendents (left
sub-tree)
• key value in the node is less than the key value in its
right child and any of the right child’s descendents (right
sub-tree)
19
Binary Search Trees
Each node is the root of a subtree rooted at the node
20
Binary Search Tree ADT


Application level: same as List
Logic Level
 void MakeEmpty()
 bool IsEmpty()
 bool IsFull()
 int GetLength()
 RetrieveItem(ItemType &item, bool &found)
 InsertItem (ItemType item)
 DeleteItem (ItemType item)
 Print(ofstream &outFile)
 ResetTree(OrderType order)
 GetNextItem (ItemType &item, OrderType order,bool &finished)
Tree node in BST
Can you define a structure to represent a binary tree node ?
22
Recursive Count
Let’s start by counting the number of nodes in a
tree
Size?
Base cases(s)?
General case(s)?
23
Recursive Count: version 1
if (Left(tree) is NULL) AND (Right(tree) is NULL)
return 1
else
return Count (Left(tree)) + Count(Right(tree)) + 1
Apply to
these trees
24
Recursive Count: version 2
if (left(tree) is NULL) AND (Right(tree) is NULL)
return 1
else if (Left(tree) is NULL)
return Count(Right(tree)) + 1
else if (Right(tree) is NULL)
return Count(Left(tree)) + 1
else
return Count(Left(tree)) + Count(Right(tree)) + 1
Apply to an empty tree
25
Recursive Count: version 3
if (tree is NULL)
return 0;
if (left(tree) is NULL) AND (Right(tree) is NULL)
return 1
else if (Left(tree) is NULL)
return Count(Right(tree)) + 1
else if (Right(tree) is NULL)
return Count(Left(tree)) + 1
else
return Count(Left(tree)) + Count(Right(tree)) + 1
26
Recursive Count: version 4
if (tree is NULL)
return 0
else
return Count(Left(tree)) + Count(Right(tree)) + 1
27
Recursive Count: implementation
int TreeType::GetLength() const
{
return Count(root);
)
int TreeType::Count(TreeNode* tree) const
{
if (tree == NULL)
return 0
else
return Count(tree->left) + Count(tree>right) + 1;
}
Why do we need two functions?
28
Recursive Search
‘J’
‘T’
‘E’
‘A’
‘D’
‘B’
‘Z’
‘P’
‘K’
‘L’
Are ‘D’, ‘Q’, and ‘N’ in the tree?
29
‘V’
‘M’
‘H’
‘Q’
‘S’
Recursive Search
Retrieve(tree, item, found)
Size?
Base case(s)?
General case(s)?
30
Recursive Search
void TreeType::Retrieve(TreeNode* tree,
ItemType& item, bool& found) const
{
if (tree == NULL)
found = false; //base case
else if (item.ComparedTo(tree->info) == LESS)
Retrieve(tree->left, item, found);
else if (item.ComparedTo(tree->info) == LARGER)
Retrieve(tree->right, item, found);
else
//base case
{
item = tree->info;
found = true;
}
}
31
Shape of BST



Shape depends on the order of item insertion
Insert the elements ‘J’ ‘E’ ‘F’ ‘T’ ‘A’ in that order
The first value inserted is always put in the root
‘J’
32
Shape of BST

Thereafter, each value to be inserted




compares itself to the value in the root node
moves left it is less or
moves right if it is greater
When does the process stop?
‘J’
‘E’
33
Shape of BST

Trace path to insert ‘F’
‘J’
‘E’
‘F’
34
Shape of BST

Trace path to insert ‘T’
‘J’
‘T’
‘E’
‘F’
35
Shape of BST

Trace path to insert ‘A’
‘J’
‘T’
‘E’
‘A’
36
‘F’
Shape of BST
Now build tree by inserting ‘A’ ‘E’ ‘F’ ‘J’ ‘T’ in that
order

And the moral is?
37
Recursive Insertion
Insert an item into a tree
Where does each new node get inserted?
Insert(tree, item)
if (tree is NULL)
Get a new node
Set right and left to NULL
Set info to item
Else if item is larger than tree.info
Insert(tree->right, item)
Else
Insert(tree->left, item)
38
Recursive Insertion
39
Recursive Insertion
Insert item 12
40
Recursive Insertion
How must
the tree
be
passed?
41
Recursive Insertion
void TreeType::Insert(TreeNode* & tree, ItemType item)
{
if (tree == NULL)
{ // Insertion place found.
tree = new TreeNode;
tree->right = NULL;
tree->left = NULL;
tree->info = item;
}
else if (item.ComparedTo(tree->info) == LESS)
Insert(tree->left, item);
else
Insert(tree->right, item);
}
42
Recursive Deletion
Delete ‘Z’
43
Recursive Deletion
Delete ‘R’
44
Recursive Deletion
Delete ‘Q’
45
Delete an existing item from BST
Can you summarize the three deletion cases?
1. Deleting a leaf node.
2. Deleting a node with only one child.
3. Deleting a node with two children.
46
Predecessor

Predecessor : the element whose key immediately
precedes (less than) the key of item


47
If the item node has left child, the largest element in the left
subtree (right-most child)
If the item has no left child, …
Successor

Successor: the element whose key immediately follows
(greater than) the key of item


48
If the item node has two children, the smallest element in the
right subtree (left-most child)
If the item node has no child, …
Recursive Deletion
DeleteItem(tree, item)
if (Left(tree) is NULL) AND (Right(tree) is NULL) // delete ‘Z’
Set tree to NULL
else if Left(tree) is NULL AND (Right(tree)) is not NULL, delete ‘R’
Set tree to Right(tree)
else if Right(tree) is NULL AND (Left(tree)) is not NULL
Set tree to Left(tree)
else // delete ‘Q’, maintain a binary search tree
Find predecessor
Set Info(tree) to Info(predecessor)
Delete predecessor
49
Recursive Deletion

TreeType::DeleteItem (ItemType item)


void Delete( TreeNode*& tree, ItemType item)
deletes item from a tree rooted at tree
void DeleteNode( TreeNode*& tree)
 deletes node pointed to by tree from a BST
void GetPredecessor( TreeNode* tree, ItemType&
data)
 finds data’s predecessor – the largest item in data’s left subtree
and save the info into data.



deletes item from the current object (a tree
object)
50
Recursive Deletion
// first, find which node should be deleted.
void TreeType::Delete(TreeNode*& tree,
ItemType item)
{
if (item < tree->info)
Delete(tree->left, item);
else if (item > tree->info)
Delete(tree->right, item);
else
DeleteNode(tree); // Node found
}
51
Recursive Deletion
void TreeType::DeleteNode(TreeNode*& tree)
{
ItemType data;
TreeNode* tempPtr;
tempPtr = tree;
if ( tree->left == NULL) {
tree = tree->right;
delete tempPtr;
} else if (tree->right == NULL){
tree = tree->left;
delete tempPtr;
}else{
GetPredecessor(tree->left, data);
tree->info = data;
Delete(tree->left, data);
}
}
52
Tracing this function using various examples…
Find Predecessor
void TreeType::GetPredecessor( TreeNode* tree,
ItemType& data)
{
//the largest item is located in its rightmost node.
while (tree->right != NULL)
tree = tree->right;
data = tree->info;
}



This function should be named GetLargestItem() as it
returns the largest item stored in tree rooted at tree
Why is the code not recursive?
Can you write the recursive solution?
53
Recursive Deletion
54
Traversals

Tree Traversal : visiting all the nodes of a tree


Depth-First Traversal, Breadth-First Traversal
Depth-First Traversal



55
Inorder Traversal
Preorder Traversal
Postorder Traversal
Inorder Traversal

Inorder traversal visits the root in between visiting the
left and right subtrees:


Inorder traversal only makes sense for binary trees.
Inorder(tree)
if tree is not NULL
1.
2.
3.
Inorder(Left(tree))
Visit Info(tree)
Inorder(Right(tree))
ABCDEFG
56
Preorder Traversal

Preorder traversal visits the root first.
PreOrder(tree)
if tree is not NULL

1.
2.
3.
57
Visit Info(tree)
Preorder(Left(tree))
Preorder(Right(tree))
D BA C F E G
Postorder Traversal

Postorder traversal visits the root last.
PostOrder(tree)
if tree is not NULL

1.
2.
3.
Postorder(Left(tree))
Postorder(Right(tree))
Visit Info(tree)
ACBEGFD
58
Traversals
59
Printing the Tree
Traversal Algorithm : Inorder traversal
What is the order of the output?
60
Iterator

Recall iterator functions for ADT List?




ResetList()
GetNextItem();
Binary Search Tree: ResetTree(), GetNextItem()
Provide different traversal order


61
In-order, pre-order, post-order
Use a parameter to select which traversal order
Iterator Implementation

ResetTree generates a queue of node contents in the
indicated order
 Add private data members: three queues storing ItemTypes
(tree node’s content)


QueType inQue, preQue, postQue;
GetNextItem returns next node content from the
appropriate queue
62
Iterator
void TreeType::ResetTree(OrderType order)
// Calls function to create a queue of the tree
// elements in the desired order.
{
Insert the info field of nodes in tree (given by root)
switch (order)
into preQue in pre-order
{
case PRE_ORDER : preQue = new QueueType;
PreOrder(root, preQue);
break;
case IN_ORDER : inQue = new QueueType;
InOrder(root, inQue);
break;
case POST_ORDER: postQue = new QueueType;
PostOrder(root, postQue);
break;
}
What if the queue is not empty when ResetTree() is called ?
}
63
void TreeType::GetNextItem(ItemType& item,
OrderType order, bool& finished)
{
finished = false;
switch (order)
{
case PRE_ORDER : preQue->Dequeue(item);
if (preQue->IsEmpty())
{ finished = true; delete preQue;
preQue = NULL;}
break;
case IN_ORDER
: inQue->Dequeue(item);
if (inQue->IsEmpty())
{finished = true; delete inQue;
inQue = NULL;}
break;
case POST_ORDER: postQue->Dequeue(item);
if (postQue->IsEmpty())
{finished = true; delete postQue;
postQue = NULL;}
break;
}
} 64
PreOrder() function
void PreOrder(TreeNode * treeRoot, QueType & preQue)
{
if (treeRoot!=NULL){
preQue->enqueue (treeRoot->info);
PreOrder (treeRoot->left, preQue);
PreQrder (treeRoot->right, preQue);
}
}
Hint: for recursive functions on a binary tree, making an empty tree case
your base case will lead to a cleaner and simpler code.
65
Printing the Tree
PrintTree operation
Size?
Base case(s)?
General case(s)?
66
Printing the Tree
void TreeType::PrintTree(TreeNode* tree,
std::ofstream& outFile)
{
if (tree != NULL)
{
PrintTree(tree->left, outFile);
outFile << tree->info;
PrintTree(tree->right, outFile);
}
}
Does this allow a reconstruction of the tree (same shaped)
based on the output?
67
Lab6: breadth-first traversal of tree


Visit the nodes in the order of their layers, within same
layer, visit nodes from left to right…
For the tree in figure:



D B FA C E G
Printout in this order can be used to reconstruct the
tree, why?
Could make tree printout more readable





68
D
/ \
BF
/\ /\
AC EG
BST: Destructor

Do we need a destructor?



In which order shall we delete the tree nodes?
i.e., which Traversal order: inorder, preorder, postorder?
TreeType::~TreeType(){
DeleteTree(root);
root = NULL;
}
void TreeType::DeleteTreeType(TreeNode * root){
if (root!=NULL){
DeleteTree(root->left);
DeleteTree(root->right);
delete root;
}
}

69
Yes as dynamic allocated memory is used
delete all nodes (free memory space taken by them).
Copy a Tree

Copy constructor: allow initialization of an object by
copying from an existing one




Assignment operator = overloaded





TreeType newTree(oldTree);
Syntax of a copy constructor:
TreeType::TreeType(const TreeType & originalTree);
TreeType newTree;
newTree=oldTree;
Syntax of assignment operator
Void TreeType::operator=(const TreeType & originalTree);
Both involves copying a tree

70
Use which traversal order?
 Preorder Traversal
Copying a Tree
CopyTree(copy, originalTree)
if (originalTree is NULL)
Set copy to NULL
else
Set copy to new node
Set Info(copy) to Info(originalTree)
CopyTree(Left(copy), Left(originalTree))
CopyTree(Right(copy), Right(originalTree))
How must copy be passed?
How must originalTree be passed?
71
Copy a Tree
void CopyTree (TreeNode *&copy, const TreeNode * originalTree)
{
if (originalTree==NULL)
copy=NULL;
else {
copy = new TreeNode;
copy->info = originalTree->info;
CopyTree (copy->left, originalTree->left);
CopyTree (copy->right, originalTree->right);
}
}
72
Recursive solutions so far.
Now, let’s try to solve some of the
problem iteratively….
Iterative Search

FindNode(tree, item, nodePtr, parentPtr)

Searching an item



74
If a node is found, get two pointers, one points to the node
and one points to its parent node.
If root is the node matching, the first pointers points to the
root and the second pointer points to NULL.
If no node is found, the first pointers points to NULL and the
second pointers points to its logical parent node.
Iterative Versions
FindNode(tree, item, nodePtr, parentPtr)
Set nodePtr to tree
Set parentPtr to NULL
Set found to false
while more elements to search AND NOT found
if item < Info(nodePtr) // search left subtree
Set parentPtr to nodePtr
Set nodePtr to Left(nodePtr)
else if item > Info(nodePtr) // search right subtree
Set parentPtr to nodePtr
Set nodePtr to Right(nodePtr)
else
//match
Set found to true
75
void TreeType::FindNode(TreeNode * tree, ItemType item,
TreeNode *& nodePtr, TreeNode *& parentPtr)
{
nodePtr = tree;
parentPtr = NULL;
bool found = false;
while( nodePtr != NULL & found == false)
{
if (item.ComparedTo(nodePtr->info)== LESS)
{
parentPtr = nodePtr;
nodePtr = nodePtr->left;
}else if (item.ComparedTo(nodePtr->info) == LARGER)
{
parentPtr = nodePtr;
nodePtr = nodePtr->right;
}else
found = true;
}
}
76
Iterative insertion

InsertItem




Create a node to contain the new item
Find the insertion place
Attach new node
Find the insertion place
FindNode(tree, item, nodePtr, parentPtr);

77
If no node is found, the first pointers points to NULL and the
second pointers points to its logical parent node.
Iterative Versions
Insert 13
78
Iterative Versions
79
Iterative Versions
AttachNewNode
if item < Info(parentPtr)
Set Left(parentPtr) to newNode
else
Set Right(parentPtr) to newNode
80
Iterative Version
AttachNewNode(revised)
if parentPtr equals NULL
Set tree to newNode
else if item < Info(parentPtr)
Set Left(parentPtr) to newNode
else
Set Right(parentPtr) to newNode
81
Iterative Version: DeleteItem
void TreeType::DeleteItem(ItemType item)
{
TreeNode* nodePtr;
TreeNode* parentPtr;
FindNode(root, item, nodePtr, parentPtr);
if (nodePtr == root)
DeleteNode(root);
else
if (parentPtr->left == nodePtr)
DeleteNode(parentPtr->left);
else DeleteNode(parentPtr->right);
}
Why not directly delete nodePtr?
82
Recursive Deletion: review
void TreeType::DeleteNode(TreeNode*& tree)
{
ItemType data;
TreeNode* tempPtr;
tempPtr = tree;
if ( tree->left == NULL) {
tree = tree->right;
delete tempPtr;
} else if (tree->right == NULL){
tree = tree->left;
delete tempPtr;
}else{
GetPredecessor(tree->left, data);
tree->info = data;
Delete(tree->left, data);
}
}
83
Iterative Version
parentPtr and nodePtr are external; parentPtr->left is internal (to
the tree)
84
Recursion vs. Iteration
Compare versions of Tree algorithms
Is the depth of recursion relatively shallow?
Is the recursive solution shorter or cleaner?
Is the recursive version much less efficient?
85
Nonlinked Representation
What is the mapping into the index?
86
Nonlinked Representation

For any node tree.nodes[index]
its left child is in tree.nodes[index*2 + 1]
right child is in tree.nodes[index*2 + 2]
its parent is in tree.nodes[(index - 1)/2]

87
Can you determine which nodes are leaf nodes?
Nonlinked Representation
Full Binary Tree
A binary tree in which all of the leaves are
on the same level and every nonleaf node
has two children
88
Nonlinked Representation
Complete Binary Tree
A binary tree that is either full or full
through the next-to-last level, with the
leaves on the last level as far to the left as
possible
89
Nonlinked Representation
90
Nonlinked Representation
A technique for storing a non-complete
tree
91
Binary Search Trees
The same set of keys may have different BSTs


Average depth of a node is O(log2 N)
Maximum depth of a node is O(N)
92
Time Complexity

Time complexity of Searching:


Time complexity of Inserting:


O(height of the tree)
O(height of the tree)
Time complexity of Deleting:

93
O(height of the tree)
Comparison

Assume that we have a Complete tree.
Binary Search Tree
Array-based Linear
List
Linked List
Constructor
O(1)
O(1)
O(1)
Destructor
O(N)
O(1) (non-pointers)
O(N)
MakeEmpty
O(N)
O(1)
O(N)
GetLength
O(N)
O(1)
O(1)
IsFull
O(1)
O(1)
O(1)
IsEmpty
O(1)
O(1)
O(1)
RetrieveItem
O(log2N)
O(log2N)
O(N)
InsertItem
O(log2N)
O(N)
O(N)
DeleteItem
O(log2N)
O(N)
O(N)
94
Reference


Reproduced from C++ Plus Data Structures, 4th edition
by Nell Dale.
Reproduced by permission of Jones and Bartlett
Publishers International.
95