CS61B Lecture #20: Trees and Tree Traversals, Slides of Data Structures and Algorithms

A lecture note from cs61b course at university of california, berkeley. It covers the topic of trees, their recursive structure, fundamental operation of traversal, and different types of traversals such as preorder, inorder, and postorder. The document also discusses the conversion of tree expressions to prefix, infix, and postfix notations, and the visitor pattern for tree traversals. The lecture note also touches upon the time complexity of tree traversals and iterative deepening.

Typology: Slides

2012/2013

Uploaded on 04/27/2013

netii
netii 🇮🇳

4.4

(7)

91 documents

1 / 12

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CS61B Lecture #20
Today:
Trees
Readings for Today:
Data Structures,
Chapter 5
Readings for Next Topic:
Data Structures,
Chapter 6
Last modified: Wed Mar 8 16:39:24 2006 CS61B: Lecture #20 1
pf3
pf4
pf5
pf8
pf9
pfa

Partial preview of the text

Download CS61B Lecture #20: Trees and Tree Traversals and more Slides Data Structures and Algorithms in PDF only on Docsity!

CS61B Lecture

Today:

  • Trees

Readings for Today: Data Structures, Chapter 5

Readings for Next Topic: Data Structures, Chapter 6

A Recursive Structure

  • Trees naturally represent recursively defined, hierarchical objects with more than one recursive subpart for each instance.
  • Common examples: expressions, sentences.
    • Expressions have definitions such as “an expression consists of a literal or two expressions separated by an operator.”
  • Also describe structures in which we recursively divide a set into multiple subsets.

Preorder Traversal and Prefix Expressions

Problem: Convert

x (^) +

y 3

z

⇒ (- (- (* x (+ y 3))) z)

static String toLisp (Tree T) { if (T == null) return ""; else if (T.degree () == 0) return T.label (); else { String R; R = ""; for (int i = 0; i < T.numChildren (); i += 1) R += " " + toLisp (T.child (i)); return String.format ("(%s%s)", T.label (), R); } }

Inorder Traversal and Infix Expressions

Problem: Convert

x (^) +

y 3

z

⇒ ((-(x*(y+3)))-z)

To think about: how to get rid of all those paren- theses.

static String toInfix (Tree T) { if (T == null) return ""; if (T.degree () == 0) return T.label (); else { return String.format ("(%s%s%s)", toInfix (T.left ()), T.label (), toInfix (T.right ()) } }

A General Traversal: The Visitor Pattern

void preorderTraverse (Tree T, Action whatToDo) { if (T != null) { whatToDo.action (T); for (int i = 0; i < T.numChildren (); i += 1) preorderTraverse (T.child (i), whatToDo); } }

  • What is Action?

interface Action { void action (Tree T); }

class Print implements Action | preorderTraverse (myTree, void action (Tree T) { | new Print ()); System.out.print (T.label ()); | } | } |

Times

  • The traversal algorithms have roughly the form of the boom example in §1.3.3 of Data Structures—an exponential algorithm.
  • However, the role of M in that algorithm is played by the height of the tree, not the number of nodes.
  • In fact, easy to see that tree traversal is linear: Θ(N ), where N is the # of nodes: Form of the algorithm implies that there is one visit at the root, and then one visit for every edge in the tree. Since every node but the root has exactly one parent, and the root has none, must be N − 1 edges in any non-empty tree.
  • In positional tree, is also one recursive call for each empty tree, but

    of empty trees can be no greater than kN , where k is arity.

  • For k-ary tree (max # children is k), h + 1 ≤ N ≤ k

h+1− 1 k− 1 , where^ h^ is height.

  • So h ∈ Ω(logk N ) = Ω(lg N ) and h ∈ O(N ).
  • Many tree algorithms look at one child only. For them, time is pro- portional to the height of the tree, and this is Θ(lg N ), assuming that tree is bushy—each level has about as many nodes as possible.

Iterative Deepening Time?

0

1

3

7 8

4

9 10

2

5

11 12

6

13 14

0

1

2

3

  • Let h be height, N be # of nodes.
  • Count # edges traversed (i.e, # of calls, not counting null nodes).
  • First (full) tree: 1 for level 0, 3 for level 1, 7 for level 2, 15 for level
  • Or in general (2^1 − 1) + (2^2 − 1) +... + (2h+1^ − 1) = 2h+2^ − h ∈ Θ(N ), since N = 2h+1^ − 1 for this tree.
  • Second ( right leaning) tree: 1 for level 0, 2 for level 2, 3 for level 3.
  • Or in general (h + 1)(h + 2)/2 = N (N + 1)/ 2 ∈ Θ(N 2 ), since N = h + 1 for this kind of tree.

Iterative Traversals

  • Tree recursion conceals data: a stack of nodes (all the T arguments) and a little extra information. Can make the data explicit, e.g.: void preorderTraverse2 (Tree T, Action whatToDo) { Stack s = new Stack (); s.push (T); while (! s.isEmpty ()) { Tree node = (Tree) s.pop (); if (node == null) continue; whatToDo.action (node); for (int i = node.numChildren ()-1; i >= 0; i -= 1) s.push (node.child (i)); } }
  • To do a breadth-first traversal, use a queue instead of a stack, replace push with add, and pop with removeFirst.
  • Makes breadth-first traversal worst-case linear time in all cases, but also linear space for “bushy” trees.