diff --git a/data_structures/Bag/Bag.java b/data_structures/Bag/Bag.java new file mode 100644 index 000000000000..17b5cca60a41 --- /dev/null +++ b/data_structures/Bag/Bag.java @@ -0,0 +1,123 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Scanner; + +/** + * The {@code Bag} class represents a bag (or multiset) of + * generic items. It supports insertion and iterating over the + * items in arbitrary order. + *

+ * This implementation uses a singly linked list with a static nested class Node. + * See {@link LinkedBag} for the version from the + * textbook that uses a non-static nested class. + * See {@link ResizingArrayBag} for a version that uses a resizing array. + * The add, isEmpty, and size operations + * take constant time. Iteration takes time proportional to the number of items. + *

+ * For additional documentation, see Section 1.3 of + * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + * + * @param the generic type of an item in this bag + */ +public class Bag implements Iterable { + private Node first; // beginning of bag + private int n; // number of elements in bag + + // helper linked list class + private static class Node { + private Item item; + private Node next; + } + + /** + * Initializes an empty bag. + */ + public Bag() { + first = null; + n = 0; + } + + /** + * Returns true if this bag is empty. + * + * @return {@code true} if this bag is empty; + * {@code false} otherwise + */ + public boolean isEmpty() { + return first == null; + } + + /** + * Returns the number of items in this bag. + * + * @return the number of items in this bag + */ + public int size() { + return n; + } + + /** + * Adds the item to this bag. + * + * @param item the item to add to this bag + */ + public void add(Item item) { + Node oldfirst = first; + first = new Node(); + first.item = item; + first.next = oldfirst; + n++; + } + + + /** + * Returns an iterator that iterates over the items in this bag in arbitrary order. + * + * @return an iterator that iterates over the items in this bag in arbitrary order + */ + public Iterator iterator() { + return new ListIterator(first); + } + + // an iterator, doesn't implement remove() since it's optional + private class ListIterator implements Iterator { + private Node current; + + public ListIterator(Node first) { + current = first; + } + + public boolean hasNext() { return current != null; } + public void remove() { throw new UnsupportedOperationException(); } + + public Item next() { + if (!hasNext()) throw new NoSuchElementException(); + Item item = current.item; + current = current.next; + return item; + } + } + + /** + * Unit tests the {@code Bag} data type. + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + Bag bag = new Bag(); + while (scanner.hasNext()) { + String item = scanner.next(); + bag.add(item); + } + + System.out.println("size of bag = " + bag.size()); + for (String s : bag) { + System.out.println(s); + } + } + +} \ No newline at end of file diff --git a/data_structures/Digraphs/Bag$1.class b/data_structures/Digraphs/Bag$1.class new file mode 100644 index 000000000000..f29959890110 Binary files /dev/null and b/data_structures/Digraphs/Bag$1.class differ diff --git a/data_structures/Digraphs/Bag$ListIterator.class b/data_structures/Digraphs/Bag$ListIterator.class new file mode 100644 index 000000000000..450386c281d1 Binary files /dev/null and b/data_structures/Digraphs/Bag$ListIterator.class differ diff --git a/data_structures/Digraphs/Bag$Node.class b/data_structures/Digraphs/Bag$Node.class new file mode 100644 index 000000000000..d48463f82c3b Binary files /dev/null and b/data_structures/Digraphs/Bag$Node.class differ diff --git a/data_structures/Digraphs/Bag.class b/data_structures/Digraphs/Bag.class new file mode 100644 index 000000000000..54ffc51ffe19 Binary files /dev/null and b/data_structures/Digraphs/Bag.class differ diff --git a/data_structures/Digraphs/Bag.java b/data_structures/Digraphs/Bag.java new file mode 100644 index 000000000000..17b5cca60a41 --- /dev/null +++ b/data_structures/Digraphs/Bag.java @@ -0,0 +1,123 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Scanner; + +/** + * The {@code Bag} class represents a bag (or multiset) of + * generic items. It supports insertion and iterating over the + * items in arbitrary order. + *

+ * This implementation uses a singly linked list with a static nested class Node. + * See {@link LinkedBag} for the version from the + * textbook that uses a non-static nested class. + * See {@link ResizingArrayBag} for a version that uses a resizing array. + * The add, isEmpty, and size operations + * take constant time. Iteration takes time proportional to the number of items. + *

+ * For additional documentation, see Section 1.3 of + * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + * + * @param the generic type of an item in this bag + */ +public class Bag implements Iterable { + private Node first; // beginning of bag + private int n; // number of elements in bag + + // helper linked list class + private static class Node { + private Item item; + private Node next; + } + + /** + * Initializes an empty bag. + */ + public Bag() { + first = null; + n = 0; + } + + /** + * Returns true if this bag is empty. + * + * @return {@code true} if this bag is empty; + * {@code false} otherwise + */ + public boolean isEmpty() { + return first == null; + } + + /** + * Returns the number of items in this bag. + * + * @return the number of items in this bag + */ + public int size() { + return n; + } + + /** + * Adds the item to this bag. + * + * @param item the item to add to this bag + */ + public void add(Item item) { + Node oldfirst = first; + first = new Node(); + first.item = item; + first.next = oldfirst; + n++; + } + + + /** + * Returns an iterator that iterates over the items in this bag in arbitrary order. + * + * @return an iterator that iterates over the items in this bag in arbitrary order + */ + public Iterator iterator() { + return new ListIterator(first); + } + + // an iterator, doesn't implement remove() since it's optional + private class ListIterator implements Iterator { + private Node current; + + public ListIterator(Node first) { + current = first; + } + + public boolean hasNext() { return current != null; } + public void remove() { throw new UnsupportedOperationException(); } + + public Item next() { + if (!hasNext()) throw new NoSuchElementException(); + Item item = current.item; + current = current.next; + return item; + } + } + + /** + * Unit tests the {@code Bag} data type. + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + Bag bag = new Bag(); + while (scanner.hasNext()) { + String item = scanner.next(); + bag.add(item); + } + + System.out.println("size of bag = " + bag.size()); + for (String s : bag) { + System.out.println(s); + } + } + +} \ No newline at end of file diff --git a/data_structures/Digraphs/Digraph.class b/data_structures/Digraphs/Digraph.class new file mode 100644 index 000000000000..7be47e262627 Binary files /dev/null and b/data_structures/Digraphs/Digraph.class differ diff --git a/data_structures/Digraphs/Digraph.java b/data_structures/Digraphs/Digraph.java new file mode 100644 index 000000000000..06885ab46da3 --- /dev/null +++ b/data_structures/Digraphs/Digraph.java @@ -0,0 +1,227 @@ +import java.util.NoSuchElementException; +import java.util.Stack; +import java.util.Scanner; +/** + * The {@code Digraph} class represents a directed graph of vertices + * named 0 through V - 1. + * It supports the following two primary operations: add an edge to the digraph, + * iterate over all of the vertices adjacent from a given vertex. + * Parallel edges and self-loops are permitted. + *

+ * This implementation uses an adjacency-lists representation, which + * is a vertex-indexed array of {@link Bag} objects. + * All operations take constant time (in the worst case) except + * iterating over the vertices adjacent from a given vertex, which takes + * time proportional to the number of such vertices. + *

+ * For additional documentation, + * see Section 4.2 of + * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + */ + +public class Digraph { + private static final String NEWLINE = System.getProperty("line.separator"); + + private final int V; // number of vertices in this digraph + private int E; // number of edges in this digraph + private Bag[] adj; // adj[v] = adjacency list for vertex v + private int[] indegree; // indegree[v] = indegree of vertex v + + /** + * Initializes an empty digraph with V vertices. + * + * @param V the number of vertices + * @throws IllegalArgumentException if {@code V < 0} + */ + public Digraph(int V) { + if (V < 0) throw new IllegalArgumentException("Number of vertices in a Digraph must be nonnegative"); + this.V = V; + this.E = 0; + indegree = new int[V]; + adj = (Bag[]) new Bag[V]; + for (int v = 0; v < V; v++) { + adj[v] = new Bag(); + } + } + + /** + * Initializes a digraph from the specified input stream. + * The format is the number of vertices V, + * followed by the number of edges E, + * followed by E pairs of vertices, with each entry separated by whitespace. + * + * @param in the input stream + * @throws IllegalArgumentException if the endpoints of any edge are not in prescribed range + * @throws IllegalArgumentException if the number of vertices or edges is negative + * @throws IllegalArgumentException if the input stream is in the wrong format + */ + public Digraph() { + Scanner in = new Scanner(System.in); + try { + this.V = in.nextInt(); + if (V < 0) throw new IllegalArgumentException("number of vertices in a Digraph must be nonnegative"); + indegree = new int[V]; + adj = (Bag[]) new Bag[V]; + for (int v = 0; v < V; v++) { + adj[v] = new Bag(); + } + int E = in.nextInt(); + 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.nextInt(); + int w = in.nextInt(); + addEdge(v, w); + } + } + catch (NoSuchElementException e) { + throw new IllegalArgumentException("invalid input format in Digraph constructor", e); + } + } + + /** + * Initializes a new digraph that is a deep copy of the specified digraph. + * + * @param G the digraph to copy + */ + public Digraph(Digraph G) { + this(G.V()); + this.E = G.E(); + for (int v = 0; v < V; v++) + this.indegree[v] = G.indegree(v); + for (int v = 0; v < G.V(); v++) { + // reverse so that adjacency list is in same order as original + Stack reverse = new Stack(); + for (int w : G.adj[v]) { + reverse.push(w); + } + for (int w : reverse) { + adj[v].add(w); + } + } + } + + /** + * Returns the number of vertices in this digraph. + * + * @return the number of vertices in this digraph + */ + public int V() { + return V; + } + + /** + * Returns the number of edges in this digraph. + * + * @return the number of edges in this digraph + */ + public int E() { + return E; + } + + + // throw an IllegalArgumentException unless {@code 0 <= v < V} + private void validateVertex(int v) { + if (v < 0 || v >= V) + throw new IllegalArgumentException("vertex " + v + " is not between 0 and " + (V-1)); + } + + /** + * Adds the directed edge v→w to this digraph. + * + * @param v the tail vertex + * @param w the head vertex + * @throws IllegalArgumentException unless both {@code 0 <= v < V} and {@code 0 <= w < V} + */ + public void addEdge(int v, int w) { + validateVertex(v); + validateVertex(w); + adj[v].add(w); + indegree[w]++; + E++; + } + + /** + * Returns the vertices adjacent from vertex {@code v} in this digraph. + * + * @param v the vertex + * @return the vertices adjacent from vertex {@code v} in this digraph, as an iterable + * @throws IllegalArgumentException unless {@code 0 <= v < V} + */ + public Iterable adj(int v) { + validateVertex(v); + return adj[v]; + } + + /** + * Returns the number of directed edges incident from vertex {@code v}. + * This is known as the outdegree of vertex {@code v}. + * + * @param v the vertex + * @return the outdegree of vertex {@code v} + * @throws IllegalArgumentException unless {@code 0 <= v < V} + */ + public int outdegree(int v) { + validateVertex(v); + return adj[v].size(); + } + + /** + * Returns the number of directed edges incident to vertex {@code v}. + * This is known as the indegree of vertex {@code v}. + * + * @param v the vertex + * @return the indegree of vertex {@code v} + * @throws IllegalArgumentException unless {@code 0 <= v < V} + */ + public int indegree(int v) { + validateVertex(v); + return indegree[v]; + } + + /** + * Returns the reverse of the digraph. + * + * @return the reverse of the digraph + */ + public Digraph reverse() { + Digraph reverse = new Digraph(V); + for (int v = 0; v < V; v++) { + for (int w : adj(v)) { + reverse.addEdge(w, v); + } + } + return reverse; + } + + /** + * Returns a string representation of the graph. + * + * @return the number of vertices V, followed by the number of edges E, + * followed by the V adjacency lists + */ + public String toString() { + StringBuilder s = new StringBuilder(); + s.append(V + " vertices, " + E + " edges " + NEWLINE); + for (int v = 0; v < V; v++) { + s.append(String.format("%d: ", v)); + for (int w : adj[v]) { + s.append(String.format("%d ", w)); + } + s.append(NEWLINE); + } + return s.toString(); + } + + public static void main(String args[]) { + int V = Integer.parseInt(args[0]); + Digraph G = new Digraph(V); + System.out.println(G); + G.addEdge(0,1); + System.out.println(G); + System.out.println(G.reverse()); + } + +} \ No newline at end of file