recursive data structures noter ch.3 modeling recursive structure by class hierarchy recursive...

43
Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Upload: david-harvey

Post on 04-Jan-2016

274 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Recursive data structuresnoter ch.3

Modeling recursive structure by class hierarchy

Recursive traversal of structure

Page 2: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Recursive data structure

• Recursive structure:– list, tree

• Object oriented representation– Interface– Implementing classes

• Traversal of recursive structure– External recursive method– Internal recursive method (Composite design pattern)– Visitor design pattern

Page 3: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

File system• single file • or a directory containing (smaller) file

systems

Page 4: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Binary tree

• a leaf • or an internal node (root) and two smaller trees

Page 5: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Binary tree example: recursive expression

• An expression is either– a constant, or– an operator and two smaller expressions

Page 6: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

• Recursive structure

Page 7: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Classes for modeling recursive expression

public interface Tree { }

public class Leaf implements Tree { private int value; public Leaf(int n) { value = n; } public int getValue() { return value; }}

public class Node implements Tree { private Operator op; private Tree left; private Tree right; public Node(Tree l, Operator o, Tree r) { op = o; left = l; right = r; } public Operator getOp() { return op; } public Tree getLeft() { return left; } public Tree getRight() { return right; }}

Page 8: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Enumeration type: Operator

• Recall how to make enumeration type

public enum Operator { PLUS("+"), MINUS("-"), MULT("*"), DIV("/"); private String name; private Operator(String name) { this.name = name; } public String toString() { return name; } public int apply(int left, int right) { if (this == Operator.PLUS) return left + right; if (this == Operator.MINUS) return left - right; if (this == Operator.MULT) return left * right; /* this == Operator.DIV */ return left / right; }}

Page 9: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

representation of an expression

Tree t = new Node( new Leaf(6), Operator.PLUS, new Node( new Node(new Leaf(8),Operator.MULT,new Leaf(2)), Operator.MINUS, new Leaf(1) ) );

Page 10: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

QUIZWhich UML diagram models recursive bullet

lists best?

1. 2.

3. 4.

5. I don’t know

Page 11: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Traversal of recursive structure

• traversal

– calculate value of expression

– print expression

• traversal techniques– external recursive method– internal mutually recursive methods

(composite pattern)– visitor pattern

Page 12: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

traversal: expression evaluation• post order traversal: visit children (subexpressions)

before visiting root node (operator)

evaluate(v): if v is a leaf: return number stored at v else x = evaluate(left subexpression stored at v) y = evaluate(right subexpression stored at v) return x o y (where o is operator stored at v)

Page 13: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

evaluation by single external recursive method

public int evaluate(Tree w) { int answer; if ( w instanceof Leaf ) answer = ((Leaf)w).getValue(); else { Tree l = ((Node)w).getLeft(); Tree r = ((Node)w).getRight(); Operator o = ((Node)w).getOp(); int left_answer = evaluate(l); int right_answer = evaluate(r); answer = o.apply(left_answer,right_answer); } return answer;}

instanceof-test necessary

Java technicality:lots of casts obscures the code

Page 14: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

<ul> <li>a simple bullet list</li> <li>containing smaller lists</li> <li> <ul> <li>a smaller sublist</li> <li> <ul> <li>a tiny list</li> <li>with several entries</li> </ul> </li> <li>look: recursive lists!</li> </ul> </li></ul>

For QUIZ: HTML source code

Page 15: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

QUIZ

Which – if any – errors arise?

1. Compiler error(s)

2. Runtime exceptions

3. No errors – method is correct!

4. I don’t know

public String print(HTML h) { String result = ""; if (h instanceof Text) result = h.getText(); else { result += "<ul>"; for (HTML k : h.getEntries()) result += "<li>"+print(k)+"</li>"; result += "</ul>"; } return result;}

Page 16: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

internal mutually recursive methods• Ensure that all classes implementing Tree define a getValue method

• In interface Treepublic abstract int getValue();

• in class Leaf:public int getValue() { return value; }

• in class Node:public int getValue() { return op.apply(left.getValue(),

right.getValue());}

instanceof-tests and casts are no longer

necessary!

Page 17: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Node expr1 = new Node( new Leaf(8), Operator.MULT, new Node( new Leaf(5), Operator.PLUS, new Leaf(2) ) );

Example: 8 * (5 + 2)

Page 18: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Example: 8 * (5 + 2)expr1.getValue()

Page 19: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

QUIZ

Which – if any – errors arise?

1. Compiler error(s)

2. Runtime exceptions

3. No errors!

4. I don’t know

Code in class BulletList:

public String getText() { String result = "<ul>"; for (HTML h : getEntries()) result += "<li>"+h.getText()+"</li>"; return result+"</ul>";}

Page 20: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Comparing traversal techniques

• external recursive method:– obscures code by instanceof test and casts

• internal mutually recursive methods:– for each new kind of traversal it is necessary to mess

around with the code of all classes to insert new methods

• Visitor pattern (avoids above problems):– inserts a single method in all classes once and for all– these methods make call back to problem specific

external methods

Page 21: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Visitor design pattern

• Decoupling of Tree hierarchy and problem specific traversal.

• The Tree hierarchy is prepared by adding an accept method capable of performing callback

• A problem specific traversal (such as value computation) requires an implementation of interface TreeVisitor

Page 22: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure
Page 23: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Modification of Tree classes• The recursive structure is prepared (once and for all) by adding an

accept method to Tree and all its implementing classes

• In interface Treepublic <T> T accept(TreeVisitor<T> v) ;

• In class Leafpublic <T> T accept(TreeVisitor<T> v){ return v.visitLeaf(this);}

• In class Node public <T> T accept(TreeVisitor<T> v){ return v.visitNode(this);}

callback to problem specific method

callback to problem specific methods defined

by external visitor

Page 24: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Problem specific TreeVisitor

• A problem specific traversal requires an implementation of interface TreeVisitor:

public interface TreeVisitor<T> { public T visitLeaf(Leaf l); public T visitNode(Node n);}

• For traversal, the TreeVisitor methods send the tree object an accept message.

• The accept methods in turn make call back to the appropriate visitLeaf or visitNode method

• methods visitLeaf/visitNode and accept are mutually recursive.

Page 25: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Visitor example: expression evaluation

• instanceof test not needed (handled by call back)

class EvaluateVisitor implements TreeVisitor<Integer> {

public Integer visitLeaf(Leaf l) { return l.getValue(); }

public Integer visitNode(Node n) { int l = n.getLeft().accept(this); int r = n.getRight().accept(this); return n.getOp().apply(l,r); }}

Page 26: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Example: 8 * (5 + 2)expr1.accept(new EvaluateVisitor())

Page 27: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Example: Expression evaluation

• Given some treeTree t = ...

• Evaluate by external recursive methodevaluate(t)

• or by internal mutually recursive methodst.getValue()

• or by using visitor patternt.accept(new EvaluateVisitor())

Page 28: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

QUIZ

How would you declare accept in interface HTML?1. public <E> E accept(HTMLVisitor<E> v);

2. public E accept(HTMLVisitor<E> v);

3. public String accept(HTMLVisitor<String> v);

4. public String accept(PrintVisitor v);

5. I don’t know

public class PrintVisitor implements HTMLVisitor<String> { public String visitText(Text t) { return t.getText(); }

public String visitBulletList(BulletList b) { String result = "<ul>"; for (HTML h : b.getEntries()) result += "<li>"+h.accept(this)+"</li>"; return result+"</ul>”; }}

Page 29: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

traversal: printing expression• in order traversal: visit left child (subexpression) before

visiting root node (operator), and finally visit right child

text(v): if v is a leaf: return number else return "(" + text( left subexpression) + operator + text( right subexpression ) + ")"

Page 30: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Printing expression using visitor• Computing String representation of expression (printing)

class PrintVisitor implements TreeVisitor<String> {

public String visitLeaf(Leaf l) { return new Integer(l.getValue()).toString(); }

public String visitNode(Node n) { return ("(" + n.getLeft().accept(this) + n.getOp() + n.getRight().accept(this) + ")"); }}• Application: System.out.println(t.accept(new PrintVisitor()));

Page 31: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Traversal example: drawing expression

state : a current drawing position (x,y) initially (x,y) = (0,0)

drawSymbol(s): increment x and draw s;

draw(v): if v is a leaf: drawSymbol( number ); else increment y; draw( left subexpression ); decrement y; drawSymbol( operator ); increment y; draw( right subexpression ); decrement y;

pseudocode ignores connection lines.

Page 32: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Adding connection lines to drawingstate : a current drawing position (x,y) initially (x,y) = (0,0)drawSymbol(s): // returns position where s is drawn increment x and draw s; return (x,y)draw(v): // returns where root of expression is drawn if v is a leaf: return drawSymbol( number ); else increment y; l = draw( left subexpression ); decrement y; c = drawSymbol( operator ); draw line from l to c; increment y; r = draw( right subexpression ); decrement y; draw line from r to c; return c;

drawing of connection lines requires that

draw methods return positions for later use

Page 33: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

class Draw ...class DrawVisitor extends JComponent implements

TreeVisitor<Point> { private static final int UNIT = 30; private Tree t; private Point pen_pos; private Graphics2D g; public DrawVisitor(Tree t) { this.t = t; JFrame f = new JFrame(); f.add(this); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(400,400); f.setVisible(true); } ... public void paintComponent(Graphics g) { this.g = (Graphics2D)g; pen_pos = new Point(UNIT,UNIT); t.accept(this); }}

Page 34: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

... implements TreeVisitorprivate Point drawSymbol(Object ob) { pen_pos.x += UNIT; g.drawString(ob.toString(),pen_pos.x,pen_pos.y-4); return (Point) pen_pos.clone();}public Point visitLeaf(Leaf l) { return drawSymbol( new Integer(l.getValue()) );}public Point visitNode(Node n) { pen_pos.y += UNIT; Point left_pos = n.getLeft().accept(this); pen_pos.y -= UNIT; Point node = drawSymbol(n.getOp()); g.draw(new Line2D.Double(left_pos,node)); pen_pos.y += UNIT; Point right_pos = n.getRight().accept(this); pen_pos.y -= UNIT; g.draw(new Line2D.Double(right_pos,node)); return node;}

Page 35: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

• Actual drawing made by new DrawVisitor(t)

• where Tree t = new Node(new Leaf(6),Operator.PLUS, new Node(new Node(new Leaf(8),Operator.MULT, new Leaf(2)),Operator.MINUS,new Leaf(1)));

Page 36: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Recursive list

• the empty list

[ ]

• or an element followed by a shorter list

[ 2, 7, 13, 1]

Page 37: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

class hierarchy representing list

• Interfacepublic interface ConsList {}

• class representing empty listpublic class Nil implements ConsList {}

• class representing element and shorter listpublic class Cons implements ConsList { private Object hd; private ConsList tl; public Cons(Object x, ConsList y) { hd = x; tl = y; }}

• The list ["Easter","Xmas"] may be represented asnew Cons("Easter",new Cons("Xmas",new Nil())).

Page 38: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

public interface ConsListVisitor<T> { public T visitNil(Nil n); public T visitCons(Cons c);}

Page 39: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

ConsList classes prepared for visits

• The recursive structure is prepared (once and for all) by adding an accept method

• In interface ConsListabstract <T> T accept(ConsListVisitor<T> v);

• In class Nilpublic <T> T accept(ConsListVisitor<T> v) { return v.visitNil(this);}

• In class Conspublic <T> T accept(ConsListVisitor<T> v) { return v.visitCons(this);}

callback to problem specific method

callback to problem specific methods defined

by external visitor

Page 40: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Problem Specific ConsListVisitor: Linear Search

public class SearchVisitor implements ConsListVisitor<Boolean> {

private Object key; public SearchVisitor(Object k) { key = k; }

public Boolean visitNil(Nil n) { return false; }

public Boolean visitCons(Cons c) { return c.head().equals(key) || c.tail().accept(this); }}

• Search in recursive list l byl.accept(new SearchVisitor("Xmas"));

Page 41: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

(simple) labyrinth

• empty labyrinth • or a wall and two smaller labyrinths

=

Page 42: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

Recursive labyrinth: solving it while constructing it...

Page 43: Recursive data structures noter ch.3 Modeling recursive structure by class hierarchy Recursive traversal of structure

...solving it while constructing it