diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/out/production/FinalProject/FlightRoutesGraph$Edge.class b/out/production/FinalProject/FlightRoutesGraph$Edge.class new file mode 100644 index 0000000..f213f56 Binary files /dev/null and b/out/production/FinalProject/FlightRoutesGraph$Edge.class differ diff --git a/out/production/FinalProject/FlightRoutesGraph.class b/out/production/FinalProject/FlightRoutesGraph.class new file mode 100644 index 0000000..886fb56 Binary files /dev/null and b/out/production/FinalProject/FlightRoutesGraph.class differ diff --git a/out/production/FinalProject/Main.class b/out/production/FinalProject/Main.class new file mode 100644 index 0000000..c829684 Binary files /dev/null and b/out/production/FinalProject/Main.class differ diff --git a/out/production/FinalProject/edu/greenriver/sdev333/BSTSet$Node.class b/out/production/FinalProject/edu/greenriver/sdev333/BSTSet$Node.class new file mode 100644 index 0000000..9585dbe Binary files /dev/null and b/out/production/FinalProject/edu/greenriver/sdev333/BSTSet$Node.class differ diff --git a/out/production/FinalProject/edu/greenriver/sdev333/BSTSet.class b/out/production/FinalProject/edu/greenriver/sdev333/BSTSet.class new file mode 100644 index 0000000..503a3b2 Binary files /dev/null and b/out/production/FinalProject/edu/greenriver/sdev333/BSTSet.class differ diff --git a/out/production/FinalProject/edu/greenriver/sdev333/MathSet.class b/out/production/FinalProject/edu/greenriver/sdev333/MathSet.class new file mode 100644 index 0000000..b6d6603 Binary files /dev/null and b/out/production/FinalProject/edu/greenriver/sdev333/MathSet.class differ diff --git a/out/production/FinalProject/edu/greenriver/sdev333/Queue$LinkedListIterator.class b/out/production/FinalProject/edu/greenriver/sdev333/Queue$LinkedListIterator.class new file mode 100644 index 0000000..ed71de1 Binary files /dev/null and b/out/production/FinalProject/edu/greenriver/sdev333/Queue$LinkedListIterator.class differ diff --git a/out/production/FinalProject/edu/greenriver/sdev333/Queue$Node.class b/out/production/FinalProject/edu/greenriver/sdev333/Queue$Node.class new file mode 100644 index 0000000..8ec58ca Binary files /dev/null and b/out/production/FinalProject/edu/greenriver/sdev333/Queue$Node.class differ diff --git a/out/production/FinalProject/edu/greenriver/sdev333/Queue.class b/out/production/FinalProject/edu/greenriver/sdev333/Queue.class new file mode 100644 index 0000000..001fb4b Binary files /dev/null and b/out/production/FinalProject/edu/greenriver/sdev333/Queue.class differ diff --git a/out/production/FinalProject/edu/greenriver/sdev333/SeparateChainingHashTable.class b/out/production/FinalProject/edu/greenriver/sdev333/SeparateChainingHashTable.class new file mode 100644 index 0000000..4bb5fbd Binary files /dev/null and b/out/production/FinalProject/edu/greenriver/sdev333/SeparateChainingHashTable.class differ diff --git a/out/production/FinalProject/edu/greenriver/sdev333/SequentialSearchST$Node.class b/out/production/FinalProject/edu/greenriver/sdev333/SequentialSearchST$Node.class new file mode 100644 index 0000000..eb78483 Binary files /dev/null and b/out/production/FinalProject/edu/greenriver/sdev333/SequentialSearchST$Node.class differ diff --git a/out/production/FinalProject/edu/greenriver/sdev333/SequentialSearchST.class b/out/production/FinalProject/edu/greenriver/sdev333/SequentialSearchST.class new file mode 100644 index 0000000..504d052 Binary files /dev/null and b/out/production/FinalProject/edu/greenriver/sdev333/SequentialSearchST.class differ diff --git a/src/FlightRoutesGraph.java b/src/FlightRoutesGraph.java new file mode 100644 index 0000000..5620536 --- /dev/null +++ b/src/FlightRoutesGraph.java @@ -0,0 +1,78 @@ +import edu.greenriver.sdev333.BSTSet; +import edu.greenriver.sdev333.MathSet; +import edu.greenriver.sdev333.SeparateChainingHashTable; + +import java.util.HashSet; + +public class FlightRoutesGraph { + // two sets needed to model a graph (network) + // 1. a set of vertices (points, nodes) - airports + // 2. a set of edges (connections, lines, relationships) + // ^ route between airports + + private class Edge { + private String node1; + private String node2; + + public Edge(String from, String to) { + node1 = from; + node2 = to; + } + } + + private MathSet nodes; + private MathSet edges; + + public FlightRoutesGraph() { + nodes = new BSTSet<>(); // ok here b/c strings are comparable + edges = new SeparateChainingHashTable<>(); // must use HashSet b/c edges are not comparable + } + + public void addNode(String city) { + nodes.add(city); + } + + public void addEdge(String city1, String city2) { + Edge connection = new Edge(city1, city2); + edges.add(connection); + } + + MathSet getNeighbors(String city) { + MathSet neighbors = new BSTSet<>(); + + // loop through the edges and check + // if the city is either in node1 or node2 + for (Edge e : edges.keys()) { + if (e.node1.equals(city)) { + neighbors.add(e.node2); + } + else if (e.node2.equals(city)) { + neighbors.add(e.node1); + } + } + return neighbors; + } + + + public static void main(String[] args) { + FlightRoutesGraph g = new FlightRoutesGraph(); + + // add all the cities first (nodes) + g.addNode("JFK"); + g.addNode("ATL"); + g.addNode("HOU"); + g.addNode("ORD"); + g.addNode("DEN"); + + + // add connections between cities + g.addEdge("JFK" , "MCO"); + g.addEdge("ATL" , "MCO"); + g.addEdge("DEN" , "ORD"); + g.addEdge("ORD" , "ATL"); + + MathSet directFROMJFK = g.getNeighbors("JFK"); + MathSet directFromATL = g.getNeighbors("ATL"); + + } +} diff --git a/src/Main.java b/src/Main.java index 3e59c38..e5f6c46 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +1,57 @@ +import edu.greenriver.sdev333.BSTSet; +import edu.greenriver.sdev333.MathSet; +import edu.greenriver.sdev333.SeparateChainingHashTable; + public class Main { public static void main(String[] args) { - System.out.println("Hello world!"); + + System.out.println("BSTSet tests:"); + SeparateChainingHashTable firstSet = new SeparateChainingHashTable(); + SeparateChainingHashTable secondSet = new SeparateChainingHashTable(); + + System.out.println("isEmpty before adding to firstSet: " + firstSet.isEmpty()); + firstSet.add("a"); + firstSet.add("b"); + firstSet.add("c"); + firstSet.add("d"); + secondSet.add("a"); + secondSet.add("e"); + secondSet.add("f"); + secondSet.add("g"); + secondSet.add("h"); + System.out.println("Size after adding to firstSet = " + firstSet.size()); + + + // display each key in BST sets + System.out.println("isEmpty after adding string to set: " + firstSet.isEmpty() + " Size is now: " + firstSet.size()); + System.out.println("Iterable test - print each key in firstSet with forEach loop"); + for (String str : firstSet.keys()) { + System.out.println(str); + } + System.out.println("Second set keys:"); + for (String str : secondSet.keys()) { + System.out.println(str); + } + + // Union testing + System.out.println("Union:"); + MathSet unionSet = firstSet.union(secondSet); + for (String str : unionSet.keys()) { + System.out.println(str); + } + // Intersection testing + System.out.println("Intersection:"); + MathSet intersectionSet = firstSet.intersection(secondSet); + for (String str : intersectionSet.keys()) { + System.out.println(str); + } + // Difference testing + System.out.println("Difference:"); + MathSet differenceSet = firstSet.difference(secondSet); + for (String str : differenceSet.keys()) { + System.out.println(str); + } + + } } \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/BSTSet.java b/src/edu/greenriver/sdev333/BSTSet.java new file mode 100644 index 0000000..41e710e --- /dev/null +++ b/src/edu/greenriver/sdev333/BSTSet.java @@ -0,0 +1,245 @@ +package edu.greenriver.sdev333; + +import java.util.Iterator; + +/** + * Kevin Stone + * SDEV333: Final Project Part 1 - Implementing a Set + * + */ +public class BSTSet> implements MathSet { + + // private helper class used throughout class + private class Node { + private KeyType key; + private Node left; + private Node right; + private int N; + + public Node(KeyType key, int N) { + this.key = key; + this.N = N; + } + } + + // private field + private Node root; + + /** + * Puts the specified key into the set. + * + * @param key key to be added into the set + */ + @Override + public void add(KeyType key) { + // starts the recursion + root = addNode(root, key); + } + + // private helper method used in class + // however, Sets do not utilize values - only keys + private Node addNode(Node current, KeyType key){ + // current is the root of the subtree we are looking at + // we are now at where we are supposed to be + if(current == null) { + // create a new node + return new Node(key, 1); + } + + int cmp = key.compareTo(current.key); + // cmp will be -1 if key < currrent.key + // cmp will be 0 if key == current.key + // cmp will be 1 if key > currrent.key + + // we need to go left + if(cmp < 0) { + current.left = addNode(current.left, key); + } + // we need to go right + else if(cmp > 0) { + current.right = addNode(current.right, key); + } + else { + // key already exists in the set + current.key = key; + } + + // update the node's N - number of nodes in the subtree + // size of my left + size of my right + myself + current.N = size(current.left) + size(current.right) + 1; + return current; + } + + /** + * Is the key in the set? + * + * @param key key to check + * @return true if key is in the set, false otherwise + */ + @Override + public boolean contains(KeyType key) { + + // start at beginning, and look at each node's + // left and right + Node current = root; + while (current != null) { + int cmp = key.compareTo(current.key); + // cmp will be -1 if key < currrent.key + // cmp will be 0 if key == current.key + // cmp will be 1 if key > currrent.key + + // we need to go left + if(cmp < 0) { + current = current.left; + } + // we need to go right + else if(cmp > 0) { + current = current.right; + } + else { + // key already exists in the set + return true; + } + + } + return false; + } + + /** + * Is the set empty? + * + * @return true if the set is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return root == null; + } + + /** + * Number of keys in the set + * + * @return number of keys in the set. + */ + @Override + public int size() { + + return size(root); + } + + // private helper method used in class + private int size(Node current) { + if (current == null) { + return 0; + } + else { + return size(current.left) + size(current.right) + 1; + } + } + + /** + * Determine the union of this set with another specified set. + * Returns A union B, where A is this set, B is other set. + * A union B = {key | A.contains(key) OR B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to union + * @return the union of this set with other + */ + @Override + public MathSet union(MathSet other) { + + // create an empty set to return + MathSet result = new BSTSet(); + + // add each key to result set, then check the "otherSet" + // for new keys to add + for (KeyType key : this.keys()) { + result.add(key); + } + + // if key in "otherSet" is not in our resultSet - add to resultSet + for (KeyType currentKey : other.keys()) { + if (!result.contains(currentKey)) { + result.add(currentKey); + } + } + return result; + } + + /** + * Determine the intersection of this set with another specified set. + * Returns A intersect B, where A is this set, B is other set. + * A intersect B = {key | A.contains(key) AND B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to intersect + * @return the intersection of this set with other + */ + @Override + public MathSet intersection(MathSet other) { + // create an empty set to return + MathSet result = new BSTSet(); + + // if our "otherSet" contains a key from our currentSet - add key to resultSet + for(KeyType currentKey : this.keys()){ + if(other.contains(currentKey)) { + result.add(currentKey); + } + } + return result; + } + + /** + * Determine the difference of this set with another specified set. + * Returns A difference B, where A is this set, B is other set. + * A difference B = {key | A.contains(key) AND !B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to difference + * @return the difference of this set with other + */ + @Override + public MathSet difference(MathSet other) { + // create an empty set to return + MathSet result = new BSTSet(); + + // if key in setA (currentSet) is NOT in setB (otherSet) - add to resultSet + for(KeyType currentKey : this.keys()){ + if(!other.contains(currentKey)){ + result.add(currentKey); + } + } + return result; + } + + /** + * Retrieves a collection of all the keys in this set. + * + * @return a collection of all keys in this set + */ + @Override + public Iterable keys() { + + // create a new empty queue to hold my results + Queue keyQueue = new Queue<>(); + + // start the recursion, collecting results in the queue + inorder(root, keyQueue); + + // when done, return the queue + return keyQueue; + } + + // private helper method used in class, using provided Queue class + private void inorder(Node current, Queue q){ + if(current == null) { + // do nothing - end the method + return; + } + + inorder(current.left, q); + q.enqueue(current.key); + inorder(current.right, q); + + } +} diff --git a/src/edu/greenriver/sdev333/Queue.java b/src/edu/greenriver/sdev333/Queue.java index 638d71c..9d08216 100644 --- a/src/edu/greenriver/sdev333/Queue.java +++ b/src/edu/greenriver/sdev333/Queue.java @@ -3,6 +3,7 @@ import java.util.Iterator; /** + * Kevin Stone * FIFO queue, page 151 of the red book */ public class Queue implements Iterable { diff --git a/src/edu/greenriver/sdev333/SeparateChainingHashTable.java b/src/edu/greenriver/sdev333/SeparateChainingHashTable.java new file mode 100644 index 0000000..927b2e9 --- /dev/null +++ b/src/edu/greenriver/sdev333/SeparateChainingHashTable.java @@ -0,0 +1,192 @@ +package edu.greenriver.sdev333; +/** + * Kevin Stone + * SDEV333: Final Project Part 1 - Implementing a Set + * + * This class is to implement the MathSet interface. The + * SequentialSearchST class (created in-class with instructor + * Ken Hang) is used in this implementation. + */ +public class SeparateChainingHashTable implements MathSet { + // fields: + // array of linked lists - but we wrote a linked list in SequentialSearchSt + private SequentialSearchST[] st; + private int M; // M is the number of buckets + + // default constructor that calls our parameterized constructor + public SeparateChainingHashTable(){ + // default constructor + // calls the other constructor with a value + this(997); + } + + // constructor + public SeparateChainingHashTable(int M) { + // take their number of buckets and save them into the field + this.M = M; + + // create the array + st = new SequentialSearchST[M]; + + // for each position in the array, create a linked list (SequentialSearchSt) + for (int i = 0; i < M; i++) { + st[i] = new SequentialSearchST<>(); + } + } + + + /** + * Puts the specified key into the set. + * + * @param key key to be added into the set + */ + @Override + public void add(KeyType key) { + // use hash function to determine which index to add to + int indexToAddTo = hash(key); + // add here + st[indexToAddTo].put(key); + } + + // private helper method created in class to return an int + private int hash(KeyType key){ + // hash function = give me a key, I return an int (bucket#, array index) + return (key.hashCode() & 0x7fffffff ) % M; + } + + /** + * Is the key in the set? + * + * @param key key to check + * @return true if key is in the set, false otherwise + */ + @Override + public boolean contains(KeyType key) { + return get(key) != null; + } + + // use method created in class (SequentialSearchST) + // return null if not found + public KeyType get(KeyType key) { + int index = hash(key); // find the bucket number + // go into the bucket and see if it's there + return st[index].get(key); + } + + /** + * Is the set empty? + * + * @return true if the set is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return size() == 0; + } + + /** + * Number of keys in the set + * + * @return number of keys in the set. + */ + @Override + public int size() { + // iterate through each "bucket"'s linkedList + // for each of these lists, call the size method used in + // SequentialSearchST ( <- every time we "put" a key - size is incremented ) + int size = 0; + for (int i = 0; i < M; i++) { + size += st[i].size(); + } + + return size; + } + + /** + * Determine the union of this set with another specified set. + * Returns A union B, where A is this set, B is other set. + * A union B = {key | A.contains(key) OR B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to union + * @return the union of this set with other + */ + @Override + public MathSet union(MathSet other) { + + MathSet result = new SeparateChainingHashTable(M); + + // add all current keys to resultSet + for (KeyType currentKey: this.keys()) { + result.add(currentKey); + } + // add all "other" keys to resultSet + for(KeyType currentKey : other.keys()){ + result.add(currentKey); + } + return result; + } + + /** + * Determine the intersection of this set with another specified set. + * Returns A intersect B, where A is this set, B is other set. + * A intersect B = {key | A.contains(key) AND B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to intersect + * @return the intersection of this set with other + */ + @Override + public MathSet intersection(MathSet other) { + + MathSet result = new SeparateChainingHashTable(M); + + // if our current key is also in our "other" keys, add to resultSet + for (KeyType currentKey: this.keys()) { + if(other.contains(currentKey)){ + result.add(currentKey); + } + } + return result; + } + + /** + * Determine the difference of this set with another specified set. + * Returns A difference B, where A is this set, B is other set. + * A difference B = {key | A.contains(key) AND !B.contains(key)}. + * Does not change the contents of this set or the other set. + * + * @param other specified set to difference + * @return the difference of this set with other + */ + @Override + public MathSet difference(MathSet other) { + + MathSet result = new SeparateChainingHashTable(M); + + // if our current key is not in our "other" keys, add to resultSet + for (KeyType currentKey: this.keys()) { + if(!other.contains(currentKey)){ + result.add(currentKey); + } + } + return result; + } + + /** + * Retrieves a collection of all the keys in this set. + * + * @return a collection of all keys in this set + */ + @Override + public Iterable keys() { + Queue collector = new Queue<>(); + // for every bucket + for (int i = 0; i < M; i++) { + // take each key in that bucket and add it into the collector + for (KeyType key : st[i].keys()) { + collector.enqueue(key); + } + } + return collector; + } +} diff --git a/src/edu/greenriver/sdev333/SequentialSearchST.java b/src/edu/greenriver/sdev333/SequentialSearchST.java new file mode 100644 index 0000000..a343ea8 --- /dev/null +++ b/src/edu/greenriver/sdev333/SequentialSearchST.java @@ -0,0 +1,66 @@ +package edu.greenriver.sdev333; + +/** + * + */ +public class SequentialSearchST { + + // private field + private Node first; + private int size; + + // private helper class + private class Node { + // linked list node + KeyType key; + Node next; + public Node(KeyType key, Node next) { + this.key = key; + this.next = next; + } + } + + public void put(KeyType key) { + + for(Node x = first; x != null; x = x.next ){ + if(key.equals(x.key)){ + x.key = key; + return; + } + } + first = new Node(key, first); + size++; + } + + /** + * Gets the value of the key passed as a parameter + * @param key + * @return the associated value of the given key + */ + public KeyType get(KeyType key) { + + for(Node x = first; x != null; x = x.next){ + if(key.equals(x.key)){ + return x.key; + } + } + return null; + } + + public int size() { + + return size; + } + + public Iterable keys() { + + Queue keyQueue = new Queue<>(); + + Node current = first; + while(current != null) { + keyQueue.enqueue(current.key); + current = current.next; + } + return keyQueue; + } +}