Topic15 Trees PDF
Topic15 Trees PDF
Topic15 Trees PDF
CS 1037a Topic 15
Overview
General trees and terminology Binary trees and their traversals Binary search trees (BST)
a more efficient alternative to OrderedList
15-2
Related materials
from Main and Savitch Data Structures & other objects using C++
Chapter 10: Trees
- Sec. 10.1: Introduction to Trees - Sec. 10.2: Tree representations - Sec. 10.3 Binary tree nodes - Sec. 10.4 Tree traversals - Sec. 10.5 Binary Search Trees
Program Files
My Music
Desktop
Favorites
Start Menu
Adobe
Microsoft Office
15-5
15
pixels
(nodes)
7
9
6
3
1
2
2
3
1
8
2
3
1
2
2
0
9
2
7
6
direction toParent
1
5
4
3
7
2
8
3
9
seed
(root)
11
10
15-7
General Trees
Simplest tree is the empty tree: no nodes, no edges General tree is the empty tree, or a set of one or more nodes partitioned into disjoint subsets:
A single root node The subtrees of the root, also general trees, each connected to the root by a distinct edge
15-8
Root node
General Trees
15-9
General Trees
General Trees
E
General Trees
If nodes X and Y are connected by an edge and X is closer to the root than Y
X is the parent (or predecessor) of Y Y is a child (or successor) of X The ancestors of Y are X, the parent of X, the parent of the parent of X, , and the root Y, the children of Y, the children of the children of Y, etc, are descendants of X
15-12
ancestors of Y
General Trees
parent of Y
parent
edges
child of X
child of X
child
child
child
descendants of X 15-13
15
7
9
6
3
1
2
2
3
1
8
child 2
3
1 parent
2
2
0
9
2
7
6 8
5 6
3
7
2
8
3
9
root
(seed)
edges
child
11
10
General Trees
The root is the only node in a tree that has no parent Every other node has exactly one parent Leaves are nodes with no children An interior node is a node that is not a leaf Two nodes are siblings if they have the same parent
15-15
General Trees
A path is a sequence of edges leading from one node to another
- examples of paths from a node to the root
9
15 8
9 3
3 2
2 0
3 2
6
8
5
6
3
5
Part of the assignment was to compute a tree with optimal paths to the seed in case when a cost of a path from any given node includes weights of nodes on the path, e.g.
11 10
6=1+2+1+2
Example 1
General Trees
A path is a sequence of edges leading from one node to another The length of a path is the number of edges on the path The depth of a node N is the length of the path from the root to N The height of a tree rooted at node N is the length of the longest path from N to a leaf
15-17
General Trees
The height of a (non-empty) tree is the height of its root node In other words, the height of a tree is the length of the longest path from the root to a leaf node Height of a tree with only one node is 0 Height of the empty tree is often considered to be -1
15-18
General Trees
All nodes with depth N are said to be at level N of the tree The degree (or arity) of a node is the number of children it has The degree (or arity) of a tree is the maximum of the degrees in the trees nodes
15-19
General Trees
Level 0 Root node has degree 4; leaf nodes have degree 0
E
Level 1
Level 3
Node E has depth 1; the subtree rooted at E has height 2 Node E has degree 3
15-20
Binary Trees
Binary tree: a tree with degree (arity) 2 Each node in a binary tree has a data portion, plus references to its left and right successors Recursive nature of binary tree structure is very important when we design algorithms to operate on the tree
15-21
data item
Node* left
Node* right
15-22
15-24
Preorder Traversal
Start at the root, and use recursion:
if the tree is not empty {
/* 1 */
/* 2 */
15-25
Preorder Traversal
A B C
Well trace the different traversals using this tree; recursive calls, returns, and visits will be numbered in the order they occur
15-26
Preorder Traversal
A 2 1: visit A 24 23 45 B 3: visit B C 25: visit C 4 16 26 38 15 22 37 44 39: D 5: visit D E 17: visit E F 27: visit F G visit G 18 8 28 21 40 19 20 34 35 36 41 42 43 7 14 H 9: visit H I 29: visit I 30 33 10 13 1112 31 32
. .
. .
15-27
. .
. .
Inorder Traversal
Only difference from preorder traversal is that the data object is visited after the recursive call for the left subtree:
if the tree is not empty { Perform an inorder traversal of the left subtree of r. Visit the item at the root node r. /* 2 */ /* 1 */
Inorder Traversal
A 1 23: visit A 24 22 45 B 14: visit B C 37: visit C 2 15 25 38 13 21 36 44 41: D 5: visit D E 18: visit E F 33: visit F G visit G 16 6 26 20 39 17 19 32 34 35 40 42 43 4 12 H 9: visit H I 29: visit I 27 31 7 11 8 10 28 30
. .
. .
15-29
. .
. .
Postorder Traversal
In this case, the data object in a node is not visited until after the contents of both its subtrees have been visited:
if the tree is not empty { Perform a postorder traversal of the left subtree of r. /* 1 */
/* 3 */
15-30
Postorder Traversal
A 1 45: visit A 23 22 44 B 21: visit B C 43: visit C 2 14 24 36 13 20 35 42 41: D 12: visit D E 19: visit E F 34: visit F G visit G 15 5 25 18 37 16 17 31 32 33 38 39 40 4 11 H 10: visit H I 30: visit I 26 29 6 9 7 8 27 28
. .
. .
15-31
. .
15-32
}
NOTE: image pixels in labs 9-10 and assignment 4 form a grid (graph), not a tree. Yet, iterative traversals of tree nodes are graph nodes (e.g. image pixels) are similar. Compare this code with floodFill_xxx() based on different active front containers.
If the container is a queue, and we enqueue the left successor before the right, we get a level order traversal (analogous to Breadth-First-Search in labs 9-10)
15-35
15-36
15-37
11
(2)
01
(6)
String representing a tree can be built using a preorder traversal of the tree: visiting a node corresponds to appending two digits to the string.
00
(3)
10
(4)
00
(7)
00
(5)
11110010000100
root left and right sub-trees
01 10 00
If first digit is 1, use remainder of string to recursively build left sub-tree of root If second digit is 1, use remainder of string to recursively build right sub-tree of root
11110010000100
(4)
(6)
delete root; }
// visiting a node
(2)
15-44
15-45
15-46
Items in BST should have at least one overloaded comparison operator <, >, <=, or >=
15-47
2 3
3
(2)
7
(5)
}
2
(1)
5
(3)
8
(6)
Print out:
235578
15-49
26
26
12
19
12
19
23
23
Search for 13: visited nodes are coloured red; return false when node containing 12 has no right successor
Search for 22: return false when node containing 23 has no left successor 15-51
15-52
15-53
12
19
23
13
15-54
5 7 4
8 11
3 2
15-55
5 7 4
8 11
3 2
15-56
5 7 4
8 11
- since the node has one child only, its parent can "adopt it.
3 2
15-57
If root has a left child - return min Item removed from the left sub-tree (recursively)
Else, the root has no left child, thus its value is the minimum in the tree - save current root value as SAVED - the right child (if any) becomes a new root, the old root is deleted - return SAVED value
- in the worst case, this is O(n); - in best and average cases, its O(log2(n))
15-61
BST.h
#include Queue.h #include "StandardFunctors.h" template <class Item, class Order=IsLess> class BST { public:
class Node { public: Node( Item val, Node* ln = NULL, Node* rn=NULL ) : value(val), left(ln), right(rn) { } Item value; Node * left, *right; };
BST( ); ~BST( );
BST.h
bool isEmpty( ) const; int size( ) const; // true if BST is empty, false otherwise // number of nodes in the BST
void insert( Item item ); // insert item in a new leaf node // at an appropriate place in the tree
Item removeMin( ); // removes the minimum Item from BST // Precondition: BST should not be empty
Item removeMax( ); // removes the minimum Item from BST // Precondition: BST should not be empty // contd..
15-63
BST.h
Queue<Item> * preorder( ) const; // Return a queue that contains, in preorder traversal order, // copies of items stored inside BST
Queue<Item> * inorder( ) const; // Return a queue that contains, in inorder traversal order, // copies of items stored inside BST Queue<Item> * postorder( ) const; // Return a queue that contains, in postorder traversal order, // copies of items stored inside BST contd..
15-64
BST.h
private: Node * m_root; int m_size; void deleteSubtree( Node * &here ); // call by reference // delete the subtree rooted at here bool find( Item key, Node * here ) const; // return true if item identical to key is found in the sub-tree // rooted at here; return false otherwise void insert( Item item, Node* &here ); // call by reference // insert item in the sub-tree rooted at node here
contd..
15-65
BST.h
Item removeMax( Node* &here ); // call by reference // removes the Maximum item from the sub-tree rooted at // node here and returns its value. // PRECONDITION: sub-tree can not be empty
Item removeMin( Node* &here ); // call by reference // removes the Minimum item from the sub-tree rooted at // node here and returns its value. // PRECONDITION: sub-tree can not be empty contd..
15-66
BST.h
void preorder( Queue<Item> *q, Node * here ) const; // Traverse the nodes in the sub-tree rooted at here in preorder // fashion, and enqueue copies of Items into q in that order void inorder( Queue<Item> *q, Node * here ) const; // Traverse the nodes in the sub-tree rooted at here in inorder // fashion, and enqueue copies of Items into q in that order
void postorder( Queue<Item> *q, Node * here ) const; // Traverse the nodes in the sub-tree rooted at here in postorder // fashion, and enqueue copies of Items into q in that order
}
#include BST.template
// end of BST.h
15-67
BST.template
template <class Item, class Order> BST<Item,Order> :: BST( ) : m_root (NULL), m_size (0) { } template <class Item , class Order> BST<Item,Order> :: ~BST( ) { deleteSubtree( m_root ); // call by reference } template <class Item , class Order> bool BST<Item,Order> :: isEmpty( ) const {return (m_size == 0); }
BST.template
template <class Item , class Order> bool BST<Item,Order> :: find( Item key ) const { return find( key, m_root ); } template <class Item , class Order> void BST<Item,Order> :: insert( Item item ) { insert( item, m_root ); // call by reference } // contd..
15-69
BST.template
template <class Item , class Order> Item BST<Item,Order> :: removeMax( ) { // PRECONDITION: tree can not be empty return removeMax( m_root ); // call by reference } template <class Item , class Order> Item BST<Item,Order> :: removeMin( ) { // PRECONDITION: tree can not be empty return removeMin( m_root ); // call by reference } // contd..
15-70
BST. template
template <class Item , class Order > Queue<Item> * BST<Item,Order> :: preorder( ) const { Queue<Item> * q = new Queue<Item>( ); preorder( q, m_root ); return q; } template <class Item , class Order> Queue<Item> * BST<Item,Order> :: inorder( ) const { Queue<Item> * q = new Queue<Item>( ); inorder( q, m_root ); return q; } template <class Item , class Order> Queue<Item> * BST<Item,Order> :: postorder( ) const { Queue<Item> * q = new Queue<Item>( ); postorder( q, m_root ); return q; } // contd..
15-71
BST. template
template <class Item , class Order> void BST<Item,Order> :: deleteSubtree( Node * &here ) { if (here == NULL) return; // base case deleteSubtree( here->left ); // call by reference
BST. template
template <class Item , class Order> bool BST<Item,Order> :: find( Item key, Node * here ) const { if (here == NULL) return false; // base case Item current = here->value; if (Order::compare(key , current)) return find(key,here->left);
else if (Order::compare(current , key)) return find(key,here->right); else } /* "current == key" */ return true; // contd..
15-73
BST. template
template <class Item, class Order> void BST<Item,Order> :: insert( Item item, Node* &here ) { if ( here == NULL ) { // base case here = new Node(item); // this is where call by reference helps!!! m_size++;
}
else if (Order::compare(item , here->value)) insert(item,here->left); else insert(item,here->right);
// contd..
15-74
BST. template
template <class Item, class Order> Item BST<Item,Order> :: removeMax( Node* &here ) {
// PRECONDITION: sub-tree can not be empty (i.e. here!=NULL) if (here->right != NULL) return removeMax(here->right);
BST. template
template <class Item, class Order> Item BST<Item,Order> :: removeMin( Node* &here ) {
// PRECONDITION: sub-tree can not be empty (i.e. here!=NULL) if (here->left != NULL) return removeMin(here->left);
BST. template
template <class Item, class Order>
15-77
BST. template
template <class Item, class Order>
15-78
BST. template
template <class Item, class Order>
15-79
15-80
15-81
- O(log2(n))
- O(log2(n))
Question: what would be complexity of enqueue and dequeue if priority queue used OrderedList container? 15-82
Priority Queue
In fact, priority queue can be implemented even more efficiently with guaranteed worst case complexity O(log2(n)) for enqueue and dequeue.
based on binary trees (heaps) different from BST - optional text-book reading: Sec. 11.1 Heaps
15-83
Summary of CS1037
dynamic and static memory allocation, pointers C++, classes, templates, object-oriented programming basic data structures: (array-based lists, linked-lists, stacks, queues, trees) basic algorithms (e.g. sorting) and analysis of their complexity
This is only where it starts... if you take Computer Science courses on algorithms, data structures, optimization, ...