Title: Data Structures
1Data Structures
- 5. Trees
- Chih-Hung Wang
- Fall 2009
- Textbook Ellis Horowitz, Sartaj Sahni and Dinesh
P. Mehta. Fundamentals of Data Structures in C
(Second Edition). Silicon Press, 2007.
2Definition
- A tree is a finite set of one or more nodes such
that - There is a specially designated node called root.
- The remaining of nodes are partitioned into n?0
disjoint sets T1, T2, , Tn, where each of these
sets is a tree. T1, T2, , Tn are called the
subtrees of the root.
3A Simple Tree
The height or depth of a tree is defined to
be maximum level of any node in tree.
The roots of the subtrees of a node X are the
children of X. X is the parent of its children.
The ancestors of a node are all the nodes along
the path from the root to that node.
LEVEL 1 2 3 4
Children of the same parent are said to be
siblings
Degree the number of subtrees of a node degree
of A 3. The degree of a tree is the maximum of
the degree of the nodes in the tree Nodes that
have degree zero are called leaf or terminal
node Others nonterminals
4Representation of Trees
- List representation
- Figure 5.2 (A(B(E(K,L)F),C(G),D(H(M),I,J)))
5Left Child-Right Sibling Representation
data
Left child
right sibling
6Representation as a Degree-Two Tree
- Rotate the right-sibling pointers in a left
child-right sibling tree clockwise by 45 degrees.
are also known as binary tree
7Two Ways of Tree Representations
left child-right sibling tree
tree
binary tree
8Binary Tree
templateltclass Tgt class BinaryTree // Object A
finite set of nodes either empty or consisting of
a // root node, left BinaryTree and right
BinaryTree. public BinaryTree() // creates an
empty binary tree bool IsEmpty() // return
true iff the binary tree is empty BinaryTree(Bina
ryTreeltTgt bt1, T item, BinaryTree ltTgt
bt2) // creates a binary tree whose left
subtree is bt1, whose right subtree
// is bt2, and whose root node contains
item BinaryTreeltTgt LeftSubtree() // return the
left subtree of this BinaryTreeltTgt
RightSubtree() // return the right subtree of
this T RootData() // return the data in the
root node of this
9Skewed and Complete Binary Tree
10Properties of Binary Trees
- Lemma 5.2 Maximum number of nodes
- The maximum number of nodes on level i of a
binary tree is 2i-1, i?1. - The maximum number of nodes in a binary tree of
depth k is 2k-1, k?1.
11Lemma 5.3
- Relation between number of leaf nodes and
degree-2 nodes - For any non-empty binary tree, T, if n0 is the
number of leaf nodes and n2 the number of nodes
of degree 2, then n0 n2 1. - Definition A full binary tree of depth k is a
binary tree of depth k having 2k 1 nodes, k
0.
12Full Binary Tree and Complete Binary Tree
- Definition A binary tree with n nodes and depth
k is complete iff its nodes correspond to the
nodes numbered from 1 to n in the full binary
tree of depth k.
13Array Representation (1)
- Lemma 5.4 If a complete binary tree with n nodes
is represented sequentially, then for any node
with index i, 1 i n, we have - parent(i) is at if i ?1. If i 1, i is
at the root and has no parent. - leftChild(i) is at 2i if 2i n. If 2i gt n, then
i has no left child. - rightChild(i) is at 2i 1 if 2i 1 n. If 2i
1 gt n, then i has no right child.
14Array Representation (2)
Figure 5.10(b)
Figure 5.10(a)
15Linked Representation (1)
template ltclass Tgt class Tree //forward
declaration template ltclass Tgt class TreeNode
friend class Tree ltTgt private T
data TreeNode ltTgt leftChild TreeNode ltTgt
rightChild template ltclass Tgt class
Tree public // Tree operations . private Tre
eNode ltTgt root
16Linked Representation (2)
for Figure 5.10
17Binary Tree Traversal
- If we adopt the convention that we traverse left
before right--three traverals LVR (inorder), LRV
(postorder), and VLR (preorder). - Inorder
- Preorder
- Postorder
18Inorder/Infix form
19Inorder Traversal of a Binary Tree
- 1 template ltclass Tgt
- 2 void Tree ltTgtInorder()
- 3 // Driver calls workhorse for traversal of
entire tree. The driver is - 4 // declared as a public member function of
Tree. - 5 Inorder(root)
- 6
-
- 7 template ltclass Tgt
- 8 void Tree ltTgtInorder(TreeNode ltTgt
currentNode) - 9 // Workhorse traverses the subtree rooted at
currentNode - 10 // The workhorse is declared as a private
member function of Tree - 11 if (currrentNode)
- 12 Inorder(currentNode?leftChild)
- 13 Visit(currentNode)
- Inorder(currentNode?rightChild)
- 15
- 16
20Trace of Program 5.1
21Preorder Traversal
22Postorder Traversal
23Iterative Inorder Traversal
24Analysis of NonrecInorder
- Every step will be executed no more than some
constant times n, so the time complexity is O(n).
25Inorder Iterator Class (1)
26Inorder Iterator Class (2)
27Level-Order Traversal
- Like the order of Figure 5.11
- Use a queue
28Additional Binary Tree Operations (1)
29Additional Binary Tree Operations (2)
- Testing Equality
- Textbook page 270
30Additional Binary Tree Operations (3)
- The Satisfiability Problem
not before and before or
Time cimplexity to determine the
satisfiability O(2n)
Evaluation using postorder
31First Version of Satisfiability Algorithm
32Visiting a Node in an Expression Tree
33Threaded Binary Trees (1)
- 0 rightChild field
- Pointer to the node that would be visited after p
when traversing the tree in inorder. - 0 leftChild field
- Pointer to the node that immediately precedes
node p in inorder.
34Threaded Binary Trees (2)
Empty threaded binary tree
35Threaded Binary Trees (3)
root
36Finding the Inorder Successor
T ThreadedInorderIteratorNext () // Return
the inorder successor of currentNode in a
threaded binary tree ThreadedNode ltTgt temp
currentNode ? rightChild if (!currentNode ?
rightThread) while (!temp ? leftThread) temp
temp ? leftChild currentNode temp if
(currentNode root) return 0 else return
currentNode ? data
Right ? Left Most
37Inserting a Node
before
after
38Insertion Rule
- If s has an empty right subtree, then the
insertion is simple and diagram in Figure
5.23(a). - If the right subtree of s is not empty, then this
right subtree is made the right subtree of r
after insertion. When this is done, r becomes the
inorder predecessor of a node that has a
leftThreadtrue field, and consequently there is
an thread which has to be updated to point to r.
The node containing this thread was previously
the inorder successor of s. Figure 5.23(b)
illustrates the insertion for this case.
39Inserting r as the Right Child of s
template ltclass Tgt void ThreadedTree
ltTgtInsertRight (ThreadedNode ltTgt s,
ThreadedNode ltTgt r)// Insert r as the right
child of s. r ? rightChild s ? rightChild r
? rightThread s ? rightThread r ? leftChild
s r ? leftThread True // leftChild is a
thread s ? rightChild r s ? rightThread
false if (! r ? rightThread) ThreadedNode
ltTgt temp InorderSucc (r)
// returns the inorder successor of r temp ?
leftChild r
40Heaps
- Priority queue
- The element to be deleted is the one with highest
(or lowest) priority. - An element with arbitrary priority can be
inserted into the queue. - See Example 5.1
41A Max Priority Queue ADT
template ltclass Tgt class MaxPQ public virtual
MaxPQ () // virtual destructor virtual
bool IsEmpty () const 0 // return true iff
the priority queue is empty virtual const T Top
() const 0 // return reference to max
element virtual void Push(const T) 0 //
add an element to the priority queue virtual
void Pop () 0 // delete element with max
priority
42Max Heap (1)
- Definition A max (min) tree is a tree in which
the key value in each node is no smaller (larger)
than the key values in its children (if any). A
max heap is a complete binary tree that is also a
max tree. A min heap is a complete binary tree
that is also a min tree.
43Max Heap (2)
Max heaps
Min heaps
44Max Heap (3)
- Private
- T heap // element array
- int heapSize // number of elements
in heap - int capacity //size of the array
heap
template ltclass Tgt MaxHeapltTgtMaxHeap (int
theCapacity 10) if ( theCapacity lt 1 ) throw
Capacity must be gt 1. capacity
theCapacity heapSize 0 heap new T
capacity 1 // heap 0 is not used
45Insertion into a Max Heap (1)
Height log(n1)
O(logn)
46Insertion into a Max Heap (2)
Template ltclass Tgt void MaxHeapltTgtPush(const T
e) // Insert e into the max heap if
(heapSize capacity) // double the capacity
ChangeSize 1D(heap, capacity, 2capacity)
capacity 2 int currentNode
heapSize while (currentNode ! 1
heapcurrentNode / 2 lt e) // bubble up
heapcurrentNode heapcurrentNode / 2 //
move parent down currentNode /
2 heapcurrentNode e
47Deletion from a Heap (1)
O(logn)
48Deletion from a Heap (2)
Template ltclass Tgt void MaxHeapltTgtPop() //
Delete max element if (IsEmpty ()) throw
Heap is empty. Cannot delete. heap1.
T() // delete max element // remove last
element from heap T lastE heapheapSize--
49Deletion from a Heap (3)
// trickle down int currentNode 1 // root int
child 2 // a child of currentNode while
(child lt heapSize) // set child to larger
child of currentNode if (child lt heapSize
heapchild lt heapchild 1) child //
can we put lastE in currentNode? if (lastE gt
heapchild) break // yes // no
heapcurrentNode heapchild // move child
up currentNode child child 2 // move
down a level heapcurrentNode lastE
50Binary Search Tree
- Binary search tree has a better performance than
any of the data structures when the functions to
be performed are search, insertion, and deletion. - Definition A binary search tree is a binary
tree. It may be empty. If it is not empty then it
satisfies the following properties - Every element has a key and no two elements have
the same key (i.e., the keys are distinct) - The keys (if any) in the left subtree are smaller
than the key in the root. - The keys (if any) in the right subtree are larger
than the key in the root. - The left and right subtrees are also binary
search trees.
51BST and Not BST
Not BST
52Searching a BST
template ltclass K, class Egt // Driver pairltK, Egt
BSTltK, Egt Get(const K k) // Search the
binary search tree (this) for a pair with key
k. // If search a pair is found, return a
pointer to this pair otherwise, return 0.
return Get(root, k) template ltclass K, class
Egt // Workhorse pairltK, Egt BSTltK, Egt
Get(TreeNode ltpair ltK, Egt gt p, const K k)
if (!p) return 0 if (k lt p?data.first)
return Get(p?leftChild, k) if (k gt
p?data.first) return Get(p?rightChild, k)
return p?data
O(h) h BST with height h
Recursive search of a binary search tree
53Iterative Search of a BST
template ltclass K, class Egt // Iterative
version pairltK, Egt BSTltK, Egt Get(const K
k) TreeNode lt pairltK, Egt gt currentNode
root while (currentNode) if (k lt
currentNode ?data.first) currentNode
currentNode ?leftChild else if (k gt
currentNode ?data.first) currentNode
currentNode ?rightChild else return
currentNode ?data // no matching
pair return 0
54Searching a BST by Rank
template ltclass K, class Egt // search by
rank pairltK, Egt BSTltK, Egt RankGet(int r) //
Search the binary search tree for the rth
smallest pair. TreeNode lt pairltK, Egt gt
currentNode root while (currentNode)
if (r lt currentNode ?leftSize) currentNode
currentNode ?leftChild else if (r gt
currentNode ?leftSize) r -
currentNode ?leftSize currentNode
currentNode ?rightSize else
return currentNode ?data return 0
If we wish to search by rank, each node should
have additional field leftsize.
O(h) h BST with height h
55Example of Searching a BST by Rank
26
Leftsize13
41
17
47
30
14
21
38
28
22
19
10
16
20
7
12
35
39
15
3
Find 17th smallest node
56Insertion into a BST (1)
57Insertion into a BST (2)
template ltclass K, class Egt void BSTltK, E gt
Insert(const pairltK, E gt thePair) // Insert
thePair into the binary search tree // search
for thePair.first, pp is parent of p TreeNode
lt pairltK, Egt gt p root, pp 0 while (p)
pp p if (thePair.first lt p
?data.first) p p ?leftChild else if
(thePair.first gt p ?data.first) p p
?rightChild else // duplicate, update
associated element p ?data.second
thepair.second return // perform insertion p
new TreeNodelt pairltK, Egt gt (thePair) if (root)
// tree not empty if (thePair.first lt pp
?data.first) pp?leftChild p else
pp?rightChild p else root p
58Deletion from a BST (1)
The node has one child The node has two children
59Deletion from a BST (2)
z has only one child
60Deletion from a BST (3)
- z has two children
- Delete the replacing element
- Largest element in the left subtree
- Smallest element in the right subtree
61Selection Tree
- Winner Trees
- A winner tree is a complete binary tree in which
each node represents the smaller of its two
children. - Analysis of merging runs using winner trees.
- The time to restructure the tree is
- The time to merge all n records is
62Winner Tree for k8
run 1 run2 run3 run4 run5
run6 run7 run8
63Restructure of Tree
run 1 run2 run3 run4 run5
run6 run7 run8
64Loser Trees
65Forests
- Definition
- A forest is a set of n 0 disjoint trees.
- If we remove a root from a tree, we obtain a
forest. For example, removing the root of any
binary tree produces a forest of two trees.
66Three-tree Forest
67Transforming a Forest into a Binary Tree
- Definition If T1, , Tn is a forest of trees,
then the binary tree corresponding to this
forest, denoted by B(T1, , Tn), - is empty if n 0
- has root equal to root (T1) has left subtree
equal to B(T11, T12,, T1m), where T11, T12,,
T1m are the subtrees of root (T1) and has right
subtree B(T2, , Tn).
68Binary Tree Representation of Forest
69Disjoint Sets
- Disjoint set union If Si and Sj are two disjoint
sets, then their union Si ?Sj all elements x
such that x is in Si or Sj.
70Sets Union
71Data Representation for the Sets
72Class Definition
class Sets public // set operations
follow . . private int parent
int n // number of set elements SetsSets(int
numberOfElements) if (numberOfElements lt
2) throw Must have at least 2 elements. n
numberOfElements parent new intn
fill(parent, parent n, -1)
73Simple Functions for Union and Find
void SetsSimpleUnion(int i, int j) // Replace
the disjoint sets with roots i and j, i ! j with
their union parenti j int
SetsSimpleFind(int i) // Find the root of the
tree containing element i. while (parenti
gt 0) i parenti return i
74Analysis of SimpleUnion and SimpleFind
- Union can be proceed in time O(n)
- Find can be performed in time O(n2)
75Weighted Union
- Definition
- Weighting rule for Union(i, j) If the number
of nodes in the tree with root i is less than the
number in the tree with root j, then make j the
parent of i otherwise make i the parent of j.
76Trees Obtained Using the Weighting Rule
77Union Function
void SetsWeightedUnion(int i, int j) // Union
sets with roots i and j, i?j, using the weighting
rule. // parenti -counti and parentj
-countj int temp parenti
parentj if (parenti gt parentj) // i
has fewer nodes parenti j
parentj temp else // j has fewer
nodes (or i and j have the same number of nodes)
parentj i parenti temp
78Lemma 5.5
- Assume that we start with a forest of trees, each
having one node. Let T be a tree with m nodes
created as a result of a sequence of unions each
performed using function WeightedUnion. The
height of T is no greater than .
79Example 5.3 (I)
(a) Initial height-1 trees
(b) Height-2 trees following Union (0,1), (2,3),
(4,5) and (6,7)
80Example 5.3 (II)
(c) Height-3 trees following Union (0,2) and (4,6)
(d) Height-4 tree following Union (0,4)
81Collapsing Rule
- If j is a node on the path from i to its root and
parenti? root(i), then set parentj to root(i).
82Example 5.4 (I)
- See Example 5.3
- Perform Find(7), Find(7), , Find(7)
- Eight times
- 24 moves before collapsing
- 13 moves after collapsing
83Example 5.4 (II)
-8
-8
0
0
2
4
2
6
1
7
1
4
5
3
3
5
6
After collapsing
7
Before collapsing
373 reset three parents
84Collapsing Find
int SetsCollapsingFind(int i) // Find the root
of the tree containing element i // Use the
collapsing rule to collapse all nodes from i to
the root for (int r i parentr gt 0 r
parentr) // find root while (i ! r) //
collapse int s parenti
parenti r i s return r