Professional Documents
Culture Documents
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, ...