Graphs and Cycles.

Slides:



Advertisements
Similar presentations
AP Computer Science Anthony Keen. Computer 101 What happens when you turn a computer on? –BIOS tries to start a system loader –A system loader tries to.
Advertisements

Chapter 7. Binary Search Trees
CATHERINE AND ANNIE Python: Part 3. Intro to Loops Do you remember in Alice when you could use a loop to make a character perform an action multiple times?
The Singleton Pattern II Recursive Linked Structures.
Recursion CS 367 – Introduction to Data Structures.
Written by: Dr. JJ Shepherd
Intro Programming By Trevor Decker Team 1743 By Trevor Decker Team 1743.
Representing Relations Using Matrices
Chapter 6 Horstmann Programs that make decisions: the IF command.
ITERATIVE CONSTRUCTS: DOLIST Dolist is an iterative construct (a loop statement) consisting of a variable declaration and a body The body states what happens.
Example: HP ≤ p HC Hamiltonian Path –Input: Undirected Graph G = (V,E) –Y/N Question: Does G contain a Hamiltonian Path? Hamiltonian Cycle –Input: Undirected.
Prof. Bodik CS 164 Lecture 16, Fall Global Optimization Lecture 16.
Writing a Class (defining a data-type). Create a new project : Project (uncheck the “Create Main Class”)
Searching in a Graph CS 5010 Program Design Paradigms “Bootcamp” Lesson 8.4 TexPoint fonts used in EMF. Read the TexPoint manual before you delete this.
Solving Equations: The Addition and Multiplication Properties
(c) University of Washington04-1 CSC 143 Java Inheritance Example (Review)
Complex objects How might you design a class called NestedRects of graphical objects that look like this? Requirements for the constructor: –Like many.
Iteration. Adding CDs to Vic Stack In many of the programs you write, you would like to have a CD on the stack before the program runs. To do this, you.
By Nicholas Policelli An Introduction to Java. Basic Program Structure public class ClassName { public static void main(String[] args) { program statements.
Week 6 - Wednesday.  What did we talk about last time?  Exam 1 post-mortem  Recursive running time.
More arrays Primitive vs. reference parameters. Arrays as parameters to functions.
Rob Miles. Creating a Working MoodLight We know that colours in XNA are stored as values which represent the amount of red, blue, green and transparency.
CSC 205 Programming II Lecture 18 The Eight Queens Problem.
Applying Recursion Routing in Computer Networks. Review We’ve seen that recursion provides an elegant, simple, and (sometimes) efficient way to solve.
Graphs – Part II CS 367 – Introduction to Data Structures.
Copyright © 2011 Pearson Education, Inc. Publishing as Prentice Hall. 2.6 Solving Equations: The Addition and Multiplication Properties.
BEGINNING PROGRAMMING.  Literally – giving instructions to a computer so that it does what you want  Practically – using a programming language (such.
QUEUES What are Queues? Creating a Queue Enqueuing and Dequeuing Testing for an Empty Queue.
Fall 2002CS 150: Intro. to Computing1 Streams and File I/O (That is, Input/Output) OR How you read data from files and write data to files.
ITEC 109 Lecture 11 While loops. while loops Review Choices –1 st –2 nd to ?th –Last What happens if you only use ifs? Can you have just an else by itself?
Searching in a Graph CS 5010 Program Design Paradigms “Bootcamp” Lesson TexPoint fonts used in EMF. Read the TexPoint manual before you delete this.
Iterators ITI 1121 N. El Kadri. Motivation Given a (singly) linked-list implementation of the interface List, defined as follows, public interface List.
CS2102: Lecture on Abstract Classes and Inheritance Kathi Fisler.
Data Structures Arrays and Lists Part 2 More List Operations.
While loops. Iteration We’ve seen many places where repetition is necessary in a problem. We’ve been using the for loop for that purpose For loops are.
Coming up Implementation vs. Interface The Truth about variables Comparing strings HashMaps.
 Type Called bool  Bool has only two possible values: True and False.
Paul Ammann & Jeff Offutt
Graphs Chapter 15 introduces graphs which are probably the most general and commonly-used data structure. This lecture introduces heaps, which are used.
Lecture 14 Throwing Custom Exceptions
Depth First Seach: Output Fix
The switch Statement, and Introduction to Looping
Lecture 5: Some more Java!
Week 7 Part 2 Kyle Dewey.
Prof. Neary Adapted from slides by Dr. Katherine Gibson
CS 302 Week 11 Jim Williams, PhD.
CS2102: Lecture on Abstract Classes and Inheritance
Logical Operators, Boolean Data Types
Building Java Programs
Building Java Programs
Lesson 2: Building Blocks of Programming
Paul Ammann & Jeff Offutt
Paul Ammann & Jeff Offutt
Conditions and Ifs BIS1523 – Lecture 8.
Interfaces and Constructors
Logical assertions assertion: A statement that is either true or false. Examples: Java was created in The sky is purple. 23 is a prime number. 10.
<INSERT_WITTY_QUOTE_HERE>
Unit 3 - The while Loop - Extending the Vic class - Examples
Module 4 Loops.
Depth-First Search Graph Traversals Depth-First Search DFS.
Logical Operations In Matlab.
Building Java Programs
SE1H421 Procedural Programming LECTURE 4 Operators & Conditionals (1)
Building Java Programs
The structure of programming
ITI Introduction to Computing II Lab-12
Introduction to Programming
Methods/Functions.
Lecture 20 – Practice Exercises 4
Intro to Programming (in JavaScript)
Presentation transcript:

Graphs and Cycles

IGraph Interface

Node Class If we’re trying to see if this node has a route to itself Use this to connect two nodes Handling cycles Else add this node to the list of ones we’ve seen, then loop through the list of nodes you can reach from this current node, and recurse.

Graph Class

Examples

Let’s walk through her code with one of her examples Let’s walk through her code with one of her examples. She has: Boston -> Providence -> Hartford bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart);

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); }

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Graph’s hasRoute method just does: public boolean hasRoute(Node from, Node to) { return from.hasRoute(to, new LinkedList<Node>()); } (Calls the hasRoute method in Node class)

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = bost (Our node called “bost,” which is Boston) to = hart (Our node called “hart,” which is Hartford) visited = new LinkedList<Node>(); Step We’re On: We just called the method, so we’re just getting started.

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = bost (Our node called “bost,” which is Boston) to = hart (Our node called “hart,” which is Hartford) visited = new LinkedList<Node>(); Step We’re On: Is the node we’re trying to get to the node we’re currently at?

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = bost (Our node called “bost,” which is Boston) to = hart (Our node called “hart,” which is Hartford) visited = new LinkedList<Node>(); Step We’re On: Is the node we’re trying to get to the node we’re currently at? No, it’s not, so we won’t go inside of this if statement.

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = bost (Our node called “bost,” which is Boston) to = hart (Our node called “hart,” which is Hartford) visited = new LinkedList<Node>(); Step We’re On: Have we visited this node before? No we haven’t, so we won’t go into this if statement either.

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = bost (Our node called “bost,” which is Boston) to = hart (Our node called “hart,” which is Hartford) visited = bost Step We’re On: We’re now in this else statement. We add this, which is bost, to our visited list. Now we go into the for loop. For each node (each city) in the list of cities that bost is connected to, we recurse. The first (and only) node in bost’s getsTo list is prov, so “c” represents prov , “to” is still hart, and our “visited” now contains bost.

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = prov (Our node called “prov,” which is Providence) to = hart (Our node called “hart,” which is Hartford) visited = bost Step We’re On: Note how above I’ve changed “this” to be prov. We are now in prov’s hasRoute call. prov != hart, so we don’t go into this if statement.

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = prov (Our node called “prov,” which is Providence) to = hart (Our node called “hart,” which is Hartford) visited = bost Step We’re On: prov is not in the visited list, so we don’t go into this if statement.

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = prov (Our node called “prov,” which is Providence) to = hart (Our node called “hart,” which is Hartford) visited = bost Step We’re On: Let’s go into the else statement!

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = prov (Our node called “prov,” which is Providence) to = hart (Our node called “hart,” which is Hartford) visited = bost, prov Step We’re On: First, we updated our visited list (see above).

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = prov (Our node called “prov,” which is Providence) to = hart (Our node called “hart,” which is Hartford) visited = bost, prov Step We’re On: Now, for every node (city) in prov’s getsTo list, we loop.

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = prov (Our node called “prov,” which is Providence) to = hart (Our node called “hart,” which is Hartford) visited = bost, prov Step We’re On: We make our recursive call. “c” is hart, since in our examples we said there is an edge from prov to hart. This means hart is in prov’s getsTo list. “to” is still hart. “visited” contains bost and prov.

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = hart to = hart (Our node called “hart,” which is Hartford) visited = bost, prov Step We’re On: We made our recursive call. See the updated variables above.

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = hart to = hart (Our node called “hart,” which is Hartford) visited = bost, prov Step We’re On: this DOES equal to, so we return true! This method call is done.

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = prov (Our node called “prov,” which is Providence) to = hart (Our node called “hart,” which is Hartford) visited = bost, prov Step We’re On: Since this is recursion, we now go back to the “hasRoute” call was made on prov. Remember how we checked the line in red? Well that line returned true! Since it returned true, we can go into this if statement, which also returns true. This means our hasRoute method that we called on prov , one of the nodes in bost’s getsTo list, has returned true.

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Current Values: this = bost (Our node called “bost,” which is Boston) to = hart (Our node called “hart,” which is Hartford) visited = bost Step We’re On: We now go back to the method call “hasRoute” which was called on the node bost. See the variables above. Since the c.hasRoute(to,visited) call returned true in prov, this statement then returns true! So this whole hasRoute method has returned true. There is a route from Boston to Hartford.

class Node { private String cityname; // name of city at this node private LinkedList<Node> getsTo; // edges from this Node // constructor only takes the cityname as an argument, // initializing the getsTo list internally Node(String cityname) { this.cityname = cityname; this.getsTo = new LinkedList<Node>(); } // adds an edge from this node to the given toNode public void addEdge(Node toNode) { this.getsTo.add(toNode); // determines whether there is a route from this Node // to the given node boolean hasRoute(Node to, LinkedList<Node> visited) { if (this.equals(to)) return true; if (visited.contains(this)) return false; else { visited.add(this); for (Node c : this.getsTo) { if (c.hasRoute(to,visited)) { Example: bost = this.G.newNode("Boston"); hart = this.G.newNode("Hartford"); prov = this.G.newNode("Providence"); G.addDirectedEdge(bost,prov); G.addDirectedEdge(prov,hart); boolean testbh (Tester t) { return t.checkExpect(G.hasRoute(bost,hart), true); } Just as a note: If there was not a route from Boston to Hartford, this first for loop would have looped through all cities connected to Boston, returned false for each recursive call, and finally would have ended up in this else statement.