diff --git a/.idea/misc.xml b/.idea/misc.xml index 07115cd..05b1176 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file 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/src/FlightRoutesGraph.java b/src/FlightRoutesGraph.java new file mode 100644 index 0000000..bc5fb25 --- /dev/null +++ b/src/FlightRoutesGraph.java @@ -0,0 +1,107 @@ +import edu.greenriver.sdev333.MathSet; +import edu.greenriver.sdev333.*; + + + +public class FlightRoutesGraph +{ + // two sets need 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<>(); //BST ok here b/c strings are comparable + edges = new HashSet<>(); // must use HashSet here 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) + { + //create an empty set to hold the results + 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("ORD"); + g.addNode("ATL"); + g.addNode("MCO"); + g.addNode("DEN"); + + //add connections between cities (edges, routes) + g.addEdge("JFK","MCO"); + g.addEdge("ATL","JFK"); + g.addEdge("ATL","MCO"); + g.addEdge("DEN","ORD"); + g.addEdge("ORD","ATL"); + //more to go if you want + + // look for direct flgihts from JFK + MathSet directJFK = g.getNeighbors("JFK"); + MathSet directFromATL = g.getNeighbors("ATL"); + for (String key: directJFK.keys()) + { + System.out.println(key); + } + System.out.println(); + for (String key: directFromATL.keys()) + { + System.out.println(key); + } + + + } + + +} diff --git a/src/Main.java b/src/Main.java index 3e59c38..77eb9e5 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +1,82 @@ +import edu.greenriver.sdev333.*; + + public class Main { public static void main(String[] args) { System.out.println("Hello world!"); + //write some code to test out your methods for your set + //Create 2 sets + // add items to each of the sets (some same, some different) + + //Test + // set intersection + // set union + // set difference + + MathSet set1 = new HashSet<>(); + set1.add("Ken"); + set1.add("Tina"); + set1.add("Tyler"); + + MathSet set2 = new HashSet<>(); + set2.add("Ken"); + set2.add("Josh"); + set2.add("Tina"); + + // union set 1 and set 2, save into result 1 + MathSet result1 = set1.union(set2); + //print out keys from result1 + for(String key: result1.keys()) + { + System.out.println(key); + } + System.out.println(); + result1 = set1.intersection(set2); + //print out keys from result1 + for(String key: result1.keys()) + { + System.out.println(key); + } + System.out.println(); + result1 = set1.difference(set2); + //print out keys from result1 + for(String key: result1.keys()) + { + System.out.println(key); + } + + + MathSet set11 = new BSTSet<>(); + set11.add("A"); + set11.add("B"); + set11.add("C"); + + MathSet set22 = new BSTSet<>(); + set22.add("C"); + set22.add("D"); + set22.add("E"); + set22.add("F"); + + // union set 11 and set 22, save into result 11 + MathSet result11 = set11.union(set22); + //print out keys from result11 + for(String key: result11.keys()) + { + System.out.println(key); + } + System.out.println(); + result11 = set11.intersection(set22); + //print out keys from result11 + for(String key: result11.keys()) + { + System.out.println(key); + } + System.out.println(); + result11 = set11.difference(set22); + //print out keys from result11 + for(String key: result11.keys()) + { + System.out.println(key); + } } } \ 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..fefa90b --- /dev/null +++ b/src/edu/greenriver/sdev333/BSTSet.java @@ -0,0 +1,256 @@ +package edu.greenriver.sdev333; + +import java.util.Iterator; + +// page 398 +public class BSTSet> implements MathSet +{ + 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 ; + } + + } + + // 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) + { + root = put(root,key); + } + + private Node put(Node current, KeyType key) { + //current is the root of the subtree we are looking at + + //we are at where we are supposed to be + if (current == null) + { + return new Node(key, 1); + } + + int cmp = key.compareTo(current.key); + //cmp will be -1 (negative) if key < current.key + //cmp will be 0 (zero) if key == current.key + // cmp will be +1 (positive) if key> current.key + // go left + if(cmp < 0) + { + current.left = put(current.left, key); + } + else if(cmp > 0) + { + // go right + current.right = put(current.right, key); + } + else + { + // key already exists, replace the data(val) + // Do nothing + } + + // update the node's N - number of nodes in the subtree + 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) { + // someone gives me a key, i want to find the value that goes with that key + Node current = root; + while(current != null) + { + int cmp = key.compareTo(current.key); + //compareTo returns, neg, zero, pos. + if(cmp < 0) + { + current = current.left; + } + else if(cmp>0) + { + current = current.right; + } + else + { + return true; + } + }// end of while loop + + return false; + } + + /** + * 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() { + return size(root); + } + + + private int size(Node current) + { + if(current == null) + { + return 0; + } + else + { + return current.N; + } + } + /** + * 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 BSTSet<>(); + for(KeyType currentKey : this.keys()) + { + result.add(currentKey); + } + 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) { + MathSet result = new BSTSet<>(); + 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 that will hold the result + MathSet result = new BSTSet(); + + +/* // iterate (walk) through all items in this + Iterator itr = (Iterator) this.keys(); + while(itr.hasNext()) + { + KeyType currentKey = itr.next(); + if(!other.contains(currentKey)) + { + result.add(currentKey); + } + }*/ + + + + + for(KeyType currentKey : this.keys()) + { + if(!other.contains(currentKey)) + { + result.add(currentKey); + } + } + + + + return result; + } + + /** + * Retrieves a collection of all the keys in this set. + * tree class + * @return a collection of all keys in this set + */ + + @Override + public Iterable keys() { + // create a new empty queue to hold my results + Queue queue = new Queue<>(); + + // start the recursion, collecting results in the queue + inorder(root,queue); + + // when done, return the queue + return queue; + } + + private void inorder(Node current, Queue q ) + { + if(current == null) + { + // do nothing, end the method immediately + return; + } + + inorder(current.left,q); + q.enqueue(current.key); + inorder(current.right,q); + } +} diff --git a/src/edu/greenriver/sdev333/HashSet.java b/src/edu/greenriver/sdev333/HashSet.java new file mode 100644 index 0000000..6fa4bdc --- /dev/null +++ b/src/edu/greenriver/sdev333/HashSet.java @@ -0,0 +1,185 @@ +package edu.greenriver.sdev333; + +import java.security.Key; + +public class HashSet implements MathSet +{ + // Used SeparateChainingHashST as my model/example + // ^^^ code manages the "buckets" of the hash table + + //VVV code manages the insides of the buckets of the hash table + // a linked list is inside each bucket + // SeparateChainingHashST Depends on having SequentialSearchST + //will need to either bring in SequentialSearchST + // or write your own linked list + + /** + * Hash Table (separate chaining implementation) of Symbol Table + * Refer to p. 458-468 in Sedgewick and Wayne, Algorithms, 4th edition + * @param + */ + // fields + + private SequentialSearchSet[] st; + private int M; // M is the number of buckets + public HashSet() + { + // default constructor , takes no parameters + // call the other constructor with a value + + this(997); + } + + public HashSet(int M) { + this.M = M; + + st = new SequentialSearchSet[M]; + + //for each position in the array (for each bucket) + // create a linked list (squentialsearchse) in each bucket + for (int i = 0; i < M; i++) + { + st[i] = new SequentialSearchSet<>(); + } + } + + private int hash(KeyType key) + { + // hash function = they give me a key, i return an int(bucket #. array index) + return (key.hashCode() & 0x7fffffff) % M; + } + +// public ValueType get(KeyType key) { +// int index = hash(key); +// return st[index].get(key); +// } + + /** + * Puts the specified key into the set. + * + * @param key key to be added into the set + */ + @Override + public void add(KeyType key) { + int index = hash(key); + st[index].put(key); + } + + /** + * 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) { + //get the key if the key is not null, return true. + //might need an iterator? + //need a index helper method? + int index = hash(key); + return st[index].contains(key); + } + + /** + * Is the set empty? + * + * @return true if the set is empty, false otherwise + */ + @Override + public boolean isEmpty() { + return size() == 0; + } + + public int size() { + // go through each bucket and add up the each individual size + int sum = 0; + for(int i =0; i union(MathSet other) { + MathSet result = new HashSet<>(); + for(KeyType currentKey : this.keys()) + { + result.add(currentKey); + } + 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) { + MathSet result = new HashSet<>(); + 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 HashSet(); + + for(KeyType currentKey : this.keys()) + { + if(!other.contains(currentKey)) + { + result.add(currentKey); + } + } + return result; + } + + public Iterable keys() { + Queue collector = new Queue<>(); + for(int i = 0 ; i < M; i ++) + { + for(KeyType key : st[i].keys()) + { + collector.enqueue(key); + } + } + return collector; + } +} diff --git a/src/edu/greenriver/sdev333/Queue.java b/src/edu/greenriver/sdev333/Queue.java index 638d71c..ab4069e 100644 --- a/src/edu/greenriver/sdev333/Queue.java +++ b/src/edu/greenriver/sdev333/Queue.java @@ -12,40 +12,25 @@ private class Node { private Node next; } - // fields + // fields: private Node first; private Node last; private int size; - /** - * Constructor. Creates an empty queue. - */ public Queue() { first = null; last = null; size = 0; } - /** - * Check if the queue is empty. - * @return true if the queue is empty, false otherwise - */ public boolean isEmpty() { return first == null; } - /** - * Number of items in the queue. - * @return the number of items in the queue - */ public int size() { return size; } - /** - * Adds a specified item to the rear of the queue. - * @param item item to be added - */ public void enqueue(ItemType item) { Node oldlast = last; last = new Node(); @@ -62,10 +47,6 @@ public void enqueue(ItemType item) { size++; } - /** - * Removes and returns the item at the front of the queue. - * @return the item that was at the front of the queue before it was removed - */ public ItemType dequeue() { ItemType item = first.data; first = first.next; @@ -78,6 +59,7 @@ public ItemType dequeue() { /** * Returns an iterator over elements of type {@code T}. + * * @return an Iterator. */ @Override @@ -104,4 +86,4 @@ public ItemType next() { return item; } } -} +} \ No newline at end of file diff --git a/src/edu/greenriver/sdev333/SequentialSearchSet.java b/src/edu/greenriver/sdev333/SequentialSearchSet.java new file mode 100644 index 0000000..144faab --- /dev/null +++ b/src/edu/greenriver/sdev333/SequentialSearchSet.java @@ -0,0 +1,73 @@ +package edu.greenriver.sdev333; + +/** + * Sequential search (unordered linked list implementation) of Symbol Table + * Refer to p. 374-377 in Sedgewick and Wayne, Algorithms, 4th edition + * @param + */ +public class SequentialSearchSet { + + private Node first; + private int size = 0; + private class Node + { //Linked-list node + private KeyType key; + private Node next; + public Node(KeyType key, Node next) + { + this.key = key; +// this.val = val; + this.next = next; + } + + } + + + public void put(KeyType key) { + //Search for key, Update value if found; grow table if new + for(Node x = first; x != null; x = x.next) + { + if(key.equals(x.key)) + { +// x.val = value; // Search hit: update val. + //If the key already exists do nothing. + return; + } + + } + // if it doesn't exist create a new one. + first = new Node(key,first); //Search miss: add new node. + size++; + } + + + public boolean contains(KeyType key) { + //Search for key, return associated value. + for(Node x = first; x != null; x = x.next) + { + if(key.equals(x.key)) + { + return true; // search hit + } + } + return false; + } + + + public int size() { + return size; + } + + + public Iterable keys() { + Queue queue = new Queue<>(); + Node current = first; + while(current != null) + { + queue.enqueue(current.key); + current = current.next; + } + + return queue; + } +}