In: Computer Science
Java: Determining whether a tree exists in a directed graph
I'm trying to figure out how to determine if a tree exists in a directed graph, I need help with the isTree() function. the code for the Bag class used is below the main code if it's needed.
import algs13.Bag;
import java.util.HashSet;
// See instructions below
public class MyDigraph {
        static class Node {
                private String key;
                private Bag<Node> adj;
                public Node (String key) {
                        this.key = key;
                        this.adj = new Bag<> ();
                }
                public String toString () { return key; }
                public void addEdgeTo (Node n) { adj.add (n); }
                public Bag<Node> adj () { return adj; }
        }
        
        Node[] node;
        int V;
        int E;
        public static boolean DEBUG = false;
        
        public MyDigraph (int V) {
                if (V < 0) throw new IllegalArgumentException("Number of vertices in a Digraph must be nonnegative");
                this.V = V;
                this.E = 0;
                this.node = new Node[V];
                for (int i=0; i<V; i++) {
                        node[i] = new Node ("n" + (DEBUG ? i : StdRandom.uniform (100)));
                }
        }
        
        public MyDigraph(Digraph G) {
                this (G.V ()); // run the first constructor
                for (int v=0; v<V; v++) {
                        for (int w : G.adj (v))
                                addEdge(v, w);
                }
        }
        
        public MyDigraph(In in) {
                this (in.readInt()); // run the first constructor
                int E = in.readInt();
                if (E < 0) throw new IllegalArgumentException("Number of edges in a Digraph must be nonnegative");
                for (int i = 0; i < E; i++) {
                        int v = in.readInt();
                        int w = in.readInt();
                        addEdge(v, w);
                }
        }
        
        public void addEdge(int v, int w) {
                if (v < 0 || v >= V) throw new IndexOutOfBoundsException("vertex " + v + " is not between 0 and " + (V-1));
                if (w < 0 || w >= V) throw new IndexOutOfBoundsException("vertex " + w + " is not between 0 and " + (V-1));
                node[v].addEdgeTo (node[w]);
                E++;
        }
        
        public String toString() {
                StringBuilder s = new StringBuilder();
                String NEWLINE = System.getProperty("line.separator");
                s.append(V + " vertices, " + E + " edges " + NEWLINE);
                for (int v = 0; v < V; v++) {
                        s.append(String.format("%s: ", node[v]));
                        for (Node w : node[v].adj ()) {
                                s.append(String.format("%s ", w));
                        }
                        s.append(NEWLINE);
                }
                return s.toString();
        }
        
        public void toGraphviz(String filename) {
                GraphvizBuilder gb = new GraphvizBuilder ();
                for (int v = 0; v < V; v++) {
                        gb.addNode (node[v]);
                        for (Node n : node[v].adj ())
                                gb.addEdge (node[v], n);
                }
                gb.toFile (filename);
        }
// isTree returns true if the object graph rooted at node[s] is a (rooted out) tree
// (e.g. No duplicate paths or cycles)
public boolean isTree (int s) {
// TODO
return false;
}
====bag class code====
package algs13;
import stdlib.*;
public class Bag<T> implements Iterable<T> {
   private int N; // number of elements in bag
   private Node<T> first; // beginning of bag
   // helper linked list class
   private static class Node<T> {
       public Node() { }
       public T item;
       public Node<T> next;
   }
   /**
   * Create an empty stack.
   */
   public Bag() {
       first = null;
       N = 0;
   }
   /**
   * Is the BAG empty?
   */
   public boolean isEmpty() {
       return first == null;
   }
   /**
   * Return the number of items in the bag.
   */
   public int size() {
       return N;
   }
   /**
   * Add the item to the bag.
   */
   public void add(T item) {
       Node<T> oldfirst =
first;
       first = new Node<>();
       first.item = item;
       first.next = oldfirst;
       N++;
   }
   // check internal invariants
   protected static <T> boolean check(Bag<T>
that) {
       int N = that.N;
       Bag.Node<T> first =
that.first;
       if (N == 0) {
           if (first !=
null) return false;
       }
       else if (N == 1) {
           if (first ==
null) return false;
           if (first.next
!= null) return false;
       }
       else {
           if (first.next
== null) return false;
       }
       // check internal consistency of
instance variable N
       int numberOfNodes = 0;
       for (Bag.Node<T> x = first; x
!= null; x = x.next) {
          
numberOfNodes++;
       }
       if (numberOfNodes != N) return
false;
       return true;
   }
   /**
   * Return an iterator that iterates over the items in
the bag.
   */
   public Iterator<T> iterator() {
       return new ListIterator();
   }
   // an iterator, doesn't implement remove() since
it's optional
   private class ListIterator implements
Iterator<T> {
       private Node<T> current =
first;
       public boolean hasNext() {
return current != null; }
       public void remove() { throw new
UnsupportedOperationException(); }
       public T next() {
           if (!hasNext())
throw new NoSuchElementException();
           T item =
current.item;
           current =
current.next;
           return
item;
       }
   }
   /**
   * A test client.
   */
   public static void main(String[] args) {
       StdIn.fromString ("to be or not to
- be - - that - - - is");
       Bag<String> bag = new
Bag<>();
       while (!StdIn.isEmpty()) {
           String item =
StdIn.readString();
          
bag.add(item);
       }
       StdOut.println("size of bag = "
+ bag.size());
       for (String s : bag) {
          
StdOut.println(s);
       }
   }
}
import stdlib.*;
import algs13.Bag;
import algs13.Queue;
import algs41.Graph;
import java.util.HashSet;
// See instructions below
public class MyDigraph {
static class Node {
private String key;
private Bag<Node> adj;
public Node (String key) {
this.key = key;
this.adj = new Bag<> ();
}
public String toString () { return key; }
public void addEdgeTo (Node n) { adj.add (n); }
public Bag<Node> adj () { return adj; }
}
  
Node[] node;
int V;
int E;
public static boolean DEBUG = false;
  
public MyDigraph (int V) {
if (V < 0) throw new IllegalArgumentException("Number of
vertices in a Digraph must be nonnegative");
this.V = V;
this.E = 0;
this.node = new Node[V];
for (int i=0; i<V; i++) {
node[i] = new Node ("n" + (DEBUG ? i : StdRandom.uniform
(100)));
}
}
  
public MyDigraph(Digraph G) {
this (G.V ()); // run the first constructor
for (int v=0; v<V; v++) {
for (int w : G.adj (v))
addEdge(v, w);
}
}
  
public MyDigraph(In in) {
this (in.readInt()); // run the first constructor
int E = in.readInt();
if (E < 0) throw new IllegalArgumentException("Number of edges
in a Digraph must be nonnegative");
for (int i = 0; i < E; i++) {
int v = in.readInt();
int w = in.readInt();
addEdge(v, w);
}
}
  
public void addEdge(int v, int w) {
if (v < 0 || v >= V) throw new
IndexOutOfBoundsException("vertex " + v + " is not between 0 and "
+ (V-1));
if (w < 0 || w >= V) throw new
IndexOutOfBoundsException("vertex " + w + " is not between 0 and "
+ (V-1));
node[v].addEdgeTo (node[w]);
E++;
}
  
public String toString() {
StringBuilder s = new StringBuilder();
String NEWLINE = System.getProperty("line.separator");
s.append(V + " vertices, " + E + " edges " + NEWLINE);
for (int v = 0; v < V; v++) {
s.append(String.format("%s: ", node[v]));
for (Node w : node[v].adj ()) {
s.append(String.format("%s ", w));
}
s.append(NEWLINE);
}
return s.toString();
}
  
public void toGraphviz(String filename) {
GraphvizBuilder gb = new GraphvizBuilder ();
for (int v = 0; v < V; v++) {
gb.addNode (node[v]);
for (Node n : node[v].adj ())
gb.addEdge (node[v], n);
}
gb.toFile (filename);
}
// isTree returns true if the object graph rooted at node[s] is a (rooted out) tree
// (e.g. No duplicate paths or cycles)
public boolean isTree (int s) {
           boolean
nodeVisit[] = new boolean[s];
boolean cycleArray[] = new boolean[s];
for (int i = 0; i < s; i++) {
if (checkCycle(i, nodeVisit, cycleArray))
return true;
}
return false;
}
public boolean checkCycle(int vt, boolean[] nodeVisit, boolean[]
cycleArray) {
nodeVisit[vt] = true;
cycleArray[vt] = true;
for (int i = 0; i < adjList[vt].size(); i++) {
int adjVertex = adjList[vt].get(i);
if (!nodeVisit[adjVertex] && checkCycle(adjVertex,
nodeVisit, cycleArray)) {
return true;
} else if (cycleArray[adjVertex])
return true;
}
cycleArray[vt] = false;
return false;
}
}
====bag class code====
package algs13;
import stdlib.*;
public class Bag<T> implements Iterable<T> {
private int N; // number of elements in bag
private Node<T> first; // beginning of bag
// helper linked list class
private static class Node<T> {
public Node() { }
public T item;
public Node<T> next;
}
/**
* Create an empty stack.
*/
public Bag() {
first = null;
N = 0;
}
/**
* Is the BAG empty?
*/
public boolean isEmpty() {
return first == null;
}
/**
* Return the number of items in the bag.
*/
public int size() {
return N;
}
/**
* Add the item to the bag.
*/
public void add(T item) {
Node<T> oldfirst = first;
first = new Node<>();
first.item = item;
first.next = oldfirst;
N++;
}
// check internal invariants
protected static <T> boolean check(Bag<T> that) {
int N = that.N;
Bag.Node<T> first = that.first;
if (N == 0) {
if (first != null) return false;
}
else if (N == 1) {
if (first == null) return false;
if (first.next != null) return false;
}
else {
if (first.next == null) return false;
}
// check internal consistency of instance variable N
int numberOfNodes = 0;
for (Bag.Node<T> x = first; x != null; x = x.next) {
numberOfNodes++;
}
if (numberOfNodes != N) return false;
return true;
}
/**
* Return an iterator that iterates over the items in the bag.
*/
public Iterator<T> iterator() {
return new ListIterator();
}
// an iterator, doesn't implement remove() since it's
optional
private class ListIterator implements Iterator<T> {
private Node<T> current = first;
public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException();
}
public T next() {
if (!hasNext()) throw new NoSuchElementException();
T item = current.item;
current = current.next;
return item;
}
}
/**
* A test client.
*/
public static void main(String[] args) {
StdIn.fromString ("to be or not to - be - - that - - - is");
Bag<String> bag = new Bag<>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
bag.add(item);
}
StdOut.println("size of bag = " + bag.size());
for (String s : bag) {
StdOut.println(s);
}
}
}