COMP 250 Lecture 20 tree traversal Oct. 25/26, 2017 1
2
Tree Traversal How to visit (enumerate, iterate through, traverse… ) all the nodes of a tree ? 3
depthfirst (root){ // “ preorder ” if (root is not empty){ visit root for each child of root depthfirst( child ) 1 } } 4
depthfirst (root){ // “ preorder ” if (root is not empty){ visit root for each child of root depthfirst( child ) } 1 } 2 3 5
depthfirst (root){ // “ preorder ” if (root is not empty){ visit root for each child of root depthfirst( child ) } 1 } 2 3 4 5 6
depthfirst (root){ // “ preorder ” if (root is not empty){ visit root for each child of root depthfirst( child ) } 1 } 8 2 7 9 3 4 10 11 5 6 7
Preorder Traversal e.g. Printing a directory (visit = print) My Documents Documents (directory) Music (directory) Eminem (directory) Lose Yourself (file) Work Research Music Videos Raffi (directory) Shake My Sillies Out (file) Baby Beluga (file) Videos (directory) COMP Eminem Raffi : (file) 250 Work (directory) COMP250 (directory) : Research (directory) Shake my Baby Lose sillies out Beluga Yourself : 8
“Visit” implies that you do something at that node. Analogy: you aren’t visiting London UK if you just fly through Heathrow. 9
depthfirst (root){ // “ postorder ” if (root is not empty){ for each child of root depthfirst( child ) visit root } } Q: Which node is visited first? 10
depthfirst (root){ // “ postorder ” if (root is not empty){ for each child of root depthfirst( child ) visit root } } 1 11
depthfirst (root){ // “ postorder ” if (root is not empty){ for each child of root depthfirst( child ) visit root } } 1 2 12
depthfirst (root){ // “ postorder ” if (root is not empty){ for each child of root depthfirst( child ) visit root } } 5 1 4 2 3 13
depthfirst (root){ // “ postorder ” if (root is not empty){ for each child of root depthfirst( child ) visit root 11 } } 10 5 6 7 1 4 8 9 2 3 14
Example 1 postorder: recall last lecture height(v) { 4 if (v is a leaf) 3 2 1 return 0 else{ h = 0 1 0 0 2 1 for each child w of v h = max(h, height(w)) 0 1 0 0 0 return 1 + h } 0 0 } visit = return value of height 15
Example 2 Postorder: What is the total number of bytes in all files in a directory? 16
numBytes(root){ if root is a leaf return number of bytes at root else { sum = 0 for each child of root{ sum += numBytes(child) } return sum } } B y ‘visit’ here, we mean determining the number of bytes for a node, e.g. If we were to store ‘sum’ at the node. 17
NOTE: Same call sequence occurs for preorder vs postorder. Letter order corresponds to depthfirst() call order a h b g i c d j k e f 18
Call stack for depthfirst() a h b g i c d j k e f e f c d d d d d i j k b b b b b b b b b g h h h h h h h a a a a a a a a a a a a a a a a a a a a a 19
Call stack for depthfirst() a h b g i c d j k e f e f c d d d d d i j k b b b b b b b b b g h h h h h h h a a a a a a a a a a a a a a a a a a a a a 20
Call stack for depthfirst() a h b g i c d j k e f e f c d d d d d i j k b b b b b b b b b g h h h h h h h a a a a a a a a a a a a a a a a a a a a a 21
Call stack for depthfirst() a h b g i c d j k e f e f c d d d d d i j k b b b b b b b b b g h h h h h h h a a a a a a a a a a a a a a a a a a a a a 22
Tree traversal Recursive • depth first (pre- versus post-order) Non-Recursive • using a stack • using a queue 23
treeTraversalUsingStack(root){ initialize empty stack s s.push(root) while s is not empty { cur = s.pop() visit cur // moving ‘visit cur’ to be for each child of cur // after for loop s.push(child) // changes nothing } } 24
treeTraversalUsingStack(root){ initialize empty stack s s.push(root) while s is not empty { cur = s.pop() visit cur } } 25
treeTraversalUsingStack(root){ initialize empty stack s s.push(root) while s is not empty { cur = s.pop() visit cur for each child of cur s.push(child) } } 26
What is the order of nodes visited ? 27
treeTraversalUsingStack(root){ a initialize empty stack s s.push(root) while s is not empty { h b g cur = s.pop () visit cur i c d j k for each child of cur s.push(child) } e f } k j j j h i i i i i f g g g g g g g g g d e e e a _ b b b b b b b b b b b _ c c c c c c c _ 28
treeTraversalUsingStack(root){ a initialize empty stack s s.push(root) while s is not empty { h b g cur = s.pop () visit cur i c d j k for each child of cur s.push(child) } e f } k j j j h i i i i i f g g g g g g g g g d e e e a _ b b b b b b b b b b b _ c c c c c c c _ 29
treeTraversalUsingStack(root){ a initialize empty stack s s.push(root) while s is not empty { h b g cur = s.pop () visit cur i c d j k for each child of cur s.push(child) } e f } k j j j h i i i i i f g g g g g g g g g d e e e a _ b b b b b b b b b b b _ c c c c c c c _ 30
treeTraversalUsingStack(root){ a initialize empty stack s s.push(root) while s is not empty { h b g cur = s.pop () visit cur i c d j k for each child of cur s.push(child) } e f } k j j j h i i i i i f g g g g g g g g g d e e e a _ b b b b b b b b b b b _ c c c c c c c _ 31
treeTraversalUsingStack(root){ a initialize empty stack s s.push(root) while s is not empty { h b g cur = s.pop () visit cur i c d j k for each child of cur s.push(child) } e f } k j j j h i i i i i f g g g g g g g g g d e e e a _ b b b b b b b b b b b _ c c c c c c c _ 32
treeTraversalUsingStack(root){ a initialize empty stack s s.push(root) while s is not empty { h b g cur = s.pop () visit cur i c d j k for each child of cur s.push(child) } e f } k j j j h i i i i i f g g g g g g g g g d e e e a _ b b b b b b b b b b b _ c c c c c c c _ 33
treeTraversalUsingStack(root){ a initialize empty stack s s.push(root) while s is not empty { h b g cur = s.pop () visit cur i c d j k for each child of cur s.push(child) } e f } k j j j h i i i i i f g g g g g g g g g d e e e a _ b b b b b b b b b b b _ c c c c c c c _ 34
treeTraversalUsingStack(root){ a initialize empty stack s s.push(root) while s is not empty { h b g cur = s.pop () visit cur i c d j k for each child of cur s.push(child) } e f } k j j j h i i i i i f g g g g g g g g g d e e e a _ b b b b b b b b b b b _ c c c c c c c _ 35
treeTraversalUsingStack(root){ a initialize empty stack s s.push(root) while s is not empty { h b g cur = s.pop () visit cur i c d j k for each child of cur s.push(child) } e f } k j j j h i i i i i f g g g g g g g g g d e e e a _ b b b b b b b b b b b _ c c c c c c c _ 36
treeTraversalUsingStack(root){ a initialize empty stack s s.push(root) while s is not empty { h b g cur = s.pop () visit cur i c d j k for each child of cur s.push(child) } e f } k j j j h i i i i i f g g g g g g g g g d e e e a _ b b b b b b b b b b b _ c c c c c c c _ 37
Stack based method is depth first, but visits children from right to left a h b g i c d j k e f recursive abcdefghijk non-recursive (stack) ahkjigbdfec 38
Pre- or post order? treeTraversalUsingStack(root){ initialize empty stack s s.push(root) while s is not empty { cur = s.pop () Moving the visit does visit cur not make it post order. for each child of cur Why not? s.push(child) visit cur } } 39
What if we use a queue instead? treeTraversal UsingStack (root){ treeTraversal UsingQueue (root){ initialize empty stack s initialize empty queue q s.push(root) q.enqueue(root) while s is not empty { while q is not empty { cur = s.pop() cur = q.dequeue() visit cur visit cur for each child of cur for each child of cur s.push(child) q.enqueue(child) } } } } 40
treeTraversalUsingQueue(root){ Queue state initialize empty queue q at start of the q.enqueue(root) while loop while q is not empty { cur = q.dequeue() a visit cur for each child of cur q.enqueue(child) } } a d b c e f g h i j k 41
Recommend
More recommend