<<

CS206 Trees CS206 Trees Nonrecursive definition: An edge connects parent and child. A (rooted) tree consists of a of nodes, and a set of directed A node without children is a leaf. edges between nodes. Nodes with the same parent are siblings. • One node is the root; Depth of v is the length of the path from the root to v. • For every node c that is not the root, there is exactly one Height of v is the length of the longest path from v to a leaf. edge (p, c) pointing to c; How many edges does a tree with n nodes have? • For every node c there is a unique path from the root to c. A tree with n nodes has n − 1 edges. Node Depth Height A 0 3 A A B 1 1 C 1 0 D 1 1 B C D E B C D E E 1 2 F 2 0 G 2 0 F G H I J F G H I J H 2 0 I 2 0 K K J 2 1 K 3 0

CS206 Recursive definition of trees CS206 Tree examples Recursive definition: A tree consists of a root, and zero or • A company organigram more subtrees T1, T2,..., Tk. There is an edge from the root to the root of each subtree. • A filesystem Courses

CS206 CS700

What is the base case of Slides Notes Code Articles the ? • A structured document (e.g. XML, HTML) • A recursion tree ( call tree) T1 T2 T3 • An expression tree

• A decision tree CS206 Phylogenetic tree of life CS206 Decision Trees We want to write a program to decode a transmission in Morse Bacteria Archaea Eukaryota code.

GreenFilamentousbacteria To translate a letter, we make a Slimemolds Spirochetes Entamoebae Animals decision tree. Fungi Grampositives Methanosarcina Methanobacterium Halophiles Proteobacteria Plants Methanococcus E T Cyanobacteria Ciliates T. celer Planctomyces Thermoproteus Flagellates I A N M Pyrodicticum BacteroidesCytophaga Trichomonads S U R W D K G O Microsporidia Thermotoga Diplomonads H F L P B C Z Aquifex V J X Y Q

CS206 Expression trees CS206 Displaying expressions Expression(): def __str__(self): def __init__(self, data, left=None, right=None): t = self.type() self.data = data if t == "": self.left = left return str(self.data) self.right = right if t == "variable": e = Expression("*", return self.data Expression("a"), if t == "unary": # unary minus Expression("+", return "-" + str(self.left) Expression(2), # it’s a binary Expression("-", return ("(" + str(self.left) + " " + self.data expression.py Expression("b"), Expression(7)))) + " " + str(self.right) + ")") Like list nodes, tree nodes are recursively defined types. This tree has two types of leaves (for and for variables) and two types of inner nodes (for unary minus and for binary operations). CS206 Building expression trees CS206 Evaluating an expression tree: We can reuse our expression parser to build an expression tree. def evaluate(expr, vars): Each method parse_item, parse_factor, parse_term, and t = expr.type() parse_expression now returns an Expression. if t == "number": return expr.data def parse_term(tok): if t == "variable": if expr.data in vars: expr = parse_factor(tok) return vars[expr.data] t = tok[0] else: while t.isSymbol("*") or t.isSymbol("/"): raise EvalError("Undefined variable ’%s’" % expr.data) tok.pop(0) if t == "unary": rhs = parse_factor(tok) arg = evaluate(expr.left, vars) expr = Expression(t.value, expr, rhs) return -arg op = expr.data t = tok[0] lhs = evaluate(expr.left, vars) return expr rhs = evaluate(expr.right, vars) if op == "+":

return lhs + rhs evaluate.py # and so on...

CS206 Prefix notation CS206 Postfix notation The Lisp programming languages (Scheme, Racket) express Some programming languages (Forth, Postscript) are based on everything in prefix-notation: a stack, and need expressions in postfix notation: (* a (+ 2 (- b 7))) a 2 b 7 - + * def prefix(expr): def postfix(expr): t = expr.type() t = expr.type() if t == "number": if t == "number": return "%g" % expr.data return "%g" % expr.data if t == "variable": if t == "variable": return expr.data return expr.data if t == "unary": if t == "unary": return "(- " + prefix(expr.left) + ")" return postfix(expr.left) + " chs" return ("(" + expr.data + return (postfix(expr.left) + " " + " " + prefix(expr.left) + postfix(expr.right) + " " + expr.data) prepostfix.py " " + prefix(expr.right) + ")") Compilers can create this code for a stack-based processor. CS206 Tree traversals A tree traversal is the process of visiting all nodes of a tree, usually in a recursive manner.

All operations on our expression trees (evaluating, conversion to string, prefix and postfix notation of expressions) are actually tree traversals. We distinguish three main types of tree traversals, depending on when the information in a node is processed: • Preorder traversal means that a node is processed before its children; • Postorder traversal means that a node is processed after its children; • Inorder traversal means that a node is processed between its left child and its right child (and is usually only used for binary trees).