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/BasicTestClient.java b/src/BasicTestClient.java
index 38ba4d7..edae84c 100644
--- a/src/BasicTestClient.java
+++ b/src/BasicTestClient.java
@@ -1,3 +1,5 @@
+import edu.greenriver.sdev333.BST;
+import edu.greenriver.sdev333.OrderedSymbolTable;
import edu.greenriver.sdev333.SymbolTable;
import java.util.Scanner;
@@ -14,9 +16,8 @@ public static void main(String[] args) {
Scanner input = new Scanner(inputString);
- // You can replace the implementation with any class that implements
- // SymbolTable interface
- SymbolTable st = new TreeMapWrapper<>();
+ // OrderedSymbolTable interface
+ OrderedSymbolTable st = new BST<>();
int i = 0;
while (input.hasNext()) {
@@ -25,8 +26,26 @@ public static void main(String[] args) {
i++;
}
- for (String s : st.keys()) {
- System.out.println(s + " " + st.get(s));
- }
+ // Test min
+ System.out.println("Min key: " + st.min());
+
+ // Test max
+ System.out.println("Max key: " + st.max());
+
+ // Test floor
+ String floorKey = "F";
+ System.out.println("Floor of " + floorKey + ": " + st.floor(floorKey));
+
+ // Test ceiling
+ String ceilingKey = "C";
+ System.out.println("Ceiling of " + ceilingKey + ": " + st.ceiling(ceilingKey));
+
+ // Test select
+ int k = 3;
+ System.out.println("Key with rank " + k + ": " + st.select(k));
+
+ // Test rank
+ String rankKey = "E";
+ System.out.println("Rank of " + rankKey + ": " + st.rank(rankKey));
}
}
diff --git a/src/FrequencyCounter.java b/src/FrequencyCounter.java
index e43037b..0ca2e2c 100644
--- a/src/FrequencyCounter.java
+++ b/src/FrequencyCounter.java
@@ -1,9 +1,13 @@
+import edu.greenriver.sdev333.BST;
+import edu.greenriver.sdev333.BinarySearchST;
+import edu.greenriver.sdev333.SequentialSearchST;
import edu.greenriver.sdev333.SymbolTable;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.io.File;
+
/**
* Frequency Table is a symbol-table client
* This is a rewriting of what is on p. 372 in Sedgewick and Wayne, Algorithms, 4th edition
@@ -13,11 +17,11 @@
*/
public class FrequencyCounter {
public static final int MINLEN = 1;
- public static final String FILENAME = "tale.txt";
+ public static final String FILENAME = "tinyTale.txt";
public static void main(String[] args) {
System.out.println("Hello world!");
- SymbolTable st = new TreeMapWrapper<>();
+ SymbolTable st = new SequentialSearchST<>();
try {
Scanner input = new Scanner(new File(FILENAME));
diff --git a/src/edu/greenriver/sdev333/BST.java b/src/edu/greenriver/sdev333/BST.java
index 00f05f9..b559358 100644
--- a/src/edu/greenriver/sdev333/BST.java
+++ b/src/edu/greenriver/sdev333/BST.java
@@ -7,9 +7,28 @@
* @param
*/
public class BST, ValueType> implements OrderedSymbolTable {
+
+ //field
+ private Node root;
+
+ //helper class
+ private class Node {
+ private KeyType key;
+ private ValueType val;
+ private Node left;
+ private Node right;
+ private int N; //number of nodes in the subtree rooted here
+
+ public Node(KeyType key, ValueType val, int N) {
+ this.key = key;
+ this.val = val;
+ this.N = N;
+
+ }
+ }
@Override
public void put(KeyType key, ValueType value) {
-
+ root = put(root, key, value);
}
@Override
@@ -22,31 +41,132 @@ public int size() {
return 0;
}
+ private Node put(Node current, KeyType key, ValueType value) {
+ if (current == null) {
+ return new Node(key, value, 1);
+ }
+ int comp = key.compareTo(current.key);
+ if (comp < 0) {
+ current.left = put(current.left, key, value);
+ }
+ else if (comp > 0) {
+ current.right = put(current.right, key, value);
+ }
+ else {
+ current.val = value;
+ }
+ current.N = 1 + size(current.left) + size(current.right);
+ return current;
+ }
+
@Override
public KeyType min() {
- return null;
+ if (root == null) {
+ return null;
+ }
+ Node current = root;
+ while (current.left != null) {
+ current = current.left;
+ }
+ return current.key;
}
@Override
public KeyType max() {
- return null;
+ if (root == null) {
+ return null;
+ }
+ Node current = root;
+ while (current.right != null) {
+ current = current.right;
+ }
+ return current.key;
}
@Override
public KeyType floor(KeyType key) {
- return null;
+ Node x = floor(root, key);
+ if (x == null) {
+ return null;
+ }
+ return x.key;
+ }
+
+ private Node floor(Node x, KeyType key) {
+ if (x == null) {
+ return null;
+ }
+ int comp = key.compareTo(x.key);
+ if (comp == 0) {
+ return x;
+ }
+ if (comp < 0) {
+ return floor(x.left, key);
+ }
+ Node t = floor(x.right, key);
+ if (t != null) {
+ return t;
+ }
+ else {
+ return x;
+ }
}
@Override
public KeyType ceiling(KeyType key) {
- return null;
+ Node x = ceiling(root, key);
+ if (x == null) {
+ return null;
+ }
+ return x.key;
+ }
+
+ private Node ceiling(Node x, KeyType key) {
+ if (x == null) {
+ return null;
+ }
+ int comp = key.compareTo(x.key);
+ if (comp == 0) {
+ return x;
+ }
+ if (comp > 0) {
+ return ceiling(x.right, key);
+ }
+ Node t = ceiling(x.left, key);
+ if (t != null) {
+ return t;
+ }
+ else {
+ return x;
+ }
}
@Override
public int rank(KeyType key) {
+ return rank(key, root);
+ }
+
+ private int rank(KeyType key, Node x) {
+ if (x == null) {
+ return 0;
+ }
+ int comp = key.compareTo(x.key);
+ if (comp < 0) {
+ return rank(key, x.left);
+ }
+ else if (comp > 0) {
+ return 1 + size(x.left) + rank(key, x.right);
+ }
+ else {
+ return size(x.left);
+ }
+ }
+
+ private int size(Node left) {
return 0;
}
+
@Override
public KeyType select(int k) {
return null;
diff --git a/src/edu/greenriver/sdev333/BinarySearchST.java b/src/edu/greenriver/sdev333/BinarySearchST.java
index 9687778..6dd3fa9 100644
--- a/src/edu/greenriver/sdev333/BinarySearchST.java
+++ b/src/edu/greenriver/sdev333/BinarySearchST.java
@@ -7,44 +7,155 @@
* @param
*/
public class BinarySearchST, ValueType> implements OrderedSymbolTable {
+
+ private KeyType[] keys;
+ private ValueType[] values;
+ private int size;
+
+ public BinarySearchST(int capacity) {
+ keys = (KeyType[]) new Comparable[capacity];
+ values = (ValueType[]) new Object[capacity];
+ }
+
+ private void resize(int capacity) {
+ KeyType[] tempKeys = (KeyType[]) new Comparable[capacity];
+ ValueType[] tempValues = (ValueType[]) new Object[capacity];
+ for (int i = 0; i < size; i++) {
+ tempKeys[i] = keys[i];
+ tempValues[i] = values[i];
+ }
+ keys = tempKeys;
+ values = tempValues;
+ }
+
@Override
public void put(KeyType key, ValueType value) {
-
+ if (key == null) {
+ throw new IllegalArgumentException("Key cannot be null.");
+ }
+ if (value == null) {
+ delete(key);
+ return;
+ }
+ int i = rank(key);
+ if (i < size && keys[i].compareTo(key) == 0) {
+ values[i] = value;
+ return;
+ }
+ if (size == keys.length) {
+ resize(2 * keys.length);
+ }
+ for (int j = size; j > i; j--) {
+ keys[j] = keys[j-1];
+ values[j] = values[j-1];
+ }
+ keys[i] = key;
+ values[i] = value;
+ size++;
}
@Override
public ValueType get(KeyType key) {
+ if (key == null) {
+ throw new IllegalArgumentException("Key cannot be null.");
+ }
+ if (isEmpty()) {
+ return null;
+ }
+ int i = rank(key);
+ if (i < size && keys[i].compareTo(key) == 0) {
+ return values[i];
+ }
return null;
}
+ @Override
+ public void delete(KeyType key) {
+ if (key == null) {
+ throw new IllegalArgumentException("Key cannot be null.");
+ }
+ if (isEmpty()) {
+ return;
+ }
+ int i = rank(key);
+ if (i == size || keys[i].compareTo(key) != 0) {
+ return;
+ }
+ for (int j = i; j < size-1; j++) {
+ keys[j] = keys[j+1];
+ values[j] = values[j+1];
+ }
+ size--;
+ keys[size] = null;
+ values[size] = null;
+ if (size > 0 && size == keys.length/4) {
+ resize(keys.length/2);
+ }
+ }
+
@Override
public int size() {
- return 0;
+ return size;
}
@Override
public KeyType min() {
- return null;
+ if (isEmpty()) {
+ return null;
+ }
+ return keys[0];
}
@Override
public KeyType max() {
- return null;
+ if (isEmpty()) {
+ return null;
+ }
+ return keys[size-1];
}
@Override
public KeyType floor(KeyType key) {
- return null;
+ int i = rank(key);
+
+ if (i == 0) {
+ return null;
+ } else if (i < size && keys[i].compareTo(key) == 0) {
+ return keys[i];
+ } else {
+ return keys[i - 1];
+ }
}
@Override
public KeyType ceiling(KeyType key) {
- return null;
+ int i = rank(key);
+
+ if (i == size) {
+ return null;
+ } else {
+ return keys[i];
+ }
}
@Override
public int rank(KeyType key) {
- return 0;
+ int lo = 0, hi = size - 1;
+
+ while (lo <= hi) {
+ int mid = lo + (hi - lo) / 2;
+ int cmp = key.compareTo(keys[mid]);
+
+ if (cmp < 0) {
+ hi = mid - 1;
+ } else if (cmp > 0) {
+ lo = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+
+ return lo;
}
@Override
diff --git a/src/edu/greenriver/sdev333/OrderedSymbolTable.java b/src/edu/greenriver/sdev333/OrderedSymbolTable.java
index 0761e0e..6dcb8ee 100644
--- a/src/edu/greenriver/sdev333/OrderedSymbolTable.java
+++ b/src/edu/greenriver/sdev333/OrderedSymbolTable.java
@@ -14,7 +14,7 @@ default void delete(KeyType key) {
put(key, null);
}
default boolean contains(KeyType key) {
- return get(key) == null;
+ return get(key) != null;
}
default boolean isEmpty() {
return size() == 0;
diff --git a/src/edu/greenriver/sdev333/Queue.java b/src/edu/greenriver/sdev333/Queue.java
new file mode 100644
index 0000000..ab4069e
--- /dev/null
+++ b/src/edu/greenriver/sdev333/Queue.java
@@ -0,0 +1,89 @@
+package edu.greenriver.sdev333;
+
+import java.util.Iterator;
+
+/**
+ * FIFO queue, page 151 of the red book
+ */
+public class Queue implements Iterable {
+ // private helper node class:
+ private class Node {
+ private ItemType data;
+ private Node next;
+ }
+
+ // fields:
+ private Node first;
+ private Node last;
+ private int size;
+
+ public Queue() {
+ first = null;
+ last = null;
+ size = 0;
+ }
+
+ public boolean isEmpty() {
+ return first == null;
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public void enqueue(ItemType item) {
+ Node oldlast = last;
+ last = new Node();
+ last.data = item;
+ last.next = null;
+
+ if (isEmpty()) {
+ first = last;
+ }
+ else {
+ oldlast.next = last;
+ }
+
+ size++;
+ }
+
+ public ItemType dequeue() {
+ ItemType item = first.data;
+ first = first.next;
+ size--;
+ if (isEmpty()) {
+ last = null;
+ }
+ return item;
+ }
+
+ /**
+ * Returns an iterator over elements of type {@code T}.
+ *
+ * @return an Iterator.
+ */
+ @Override
+ public Iterator iterator() {
+ return new LinkedListIterator();
+ }
+
+ private class LinkedListIterator implements Iterator {
+ private Node current;
+
+ public LinkedListIterator() {
+ current = first;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return current != null;
+ }
+
+ @Override
+ public ItemType next() {
+ ItemType item = current.data;
+ current = current.next;
+ return item;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/edu/greenriver/sdev333/SeparateChainingHashST.java b/src/edu/greenriver/sdev333/SeparateChainingHashST.java
index 9f43c3c..673ef01 100644
--- a/src/edu/greenriver/sdev333/SeparateChainingHashST.java
+++ b/src/edu/greenriver/sdev333/SeparateChainingHashST.java
@@ -6,24 +6,108 @@
* @param
* @param
*/
+import java.util.ArrayList;
+
public class SeparateChainingHashST implements SymbolTable {
+ private int size; // number of key-value pairs
+ private int capacity; // hash table size
+ private ArrayList>[] st; // array of chains
+
+ private static class Node {
+ private final KeyType key;
+ private ValueType value;
+ private Node next;
+
+ public Node(KeyType key, ValueType value, Node next) {
+ this.key = key;
+ this.value = value;
+ this.next = next;
+ }
+ }
+
+ // constructor
+ public SeparateChainingHashST(int capacity) {
+ this.capacity = capacity;
+ st = (ArrayList>[]) new ArrayList[capacity];
+ for (int i = 0; i < capacity; i++) {
+ st[i] = new ArrayList>();
+ }
+ }
+
@Override
public void put(KeyType key, ValueType value) {
+ if (key == null) {
+ throw new IllegalArgumentException("Key cannot be null");
+ }
+ if (value == null) {
+ delete(key);
+ return;
+ }
+ int i = hash(key);
+ for (Node node : st[i]) {
+ if (node.key.equals(key)) {
+ node.value = value;
+ return;
+ }
+ }
+ st[i].add(new Node(key, value, null));
+ size++;
}
@Override
public ValueType get(KeyType key) {
+ if (key == null) {
+ throw new IllegalArgumentException("Key cannot be null");
+ }
+ int i = hash(key);
+ for (Node node : st[i]) {
+ if (node.key.equals(key)) {
+ return node.value;
+ }
+ }
return null;
}
+ @Override
+ public void delete(KeyType key) {
+ if (key == null) {
+ throw new IllegalArgumentException("Key cannot be null");
+ }
+ int i = hash(key);
+ Node prev = null;
+ for (Node node : st[i]) {
+ if (node.key.equals(key)) {
+ if (prev == null) {
+ st[i].remove(node);
+ } else {
+ prev.next = node.next;
+ }
+ size--;
+ return;
+ }
+ prev = node;
+ }
+ }
+
@Override
public int size() {
- return 0;
+ return size;
}
@Override
public Iterable keys() {
- return null;
+ ArrayList list = new ArrayList();
+ for (int i = 0; i < capacity; i++) {
+ for (Node node : st[i]) {
+ list.add(node.key);
+ }
+ }
+ return list;
+ }
+
+ // hash function
+ private int hash(KeyType key) {
+ return (key.hashCode() & 0x7fffffff) % capacity;
}
}
diff --git a/src/edu/greenriver/sdev333/SequentialSearchST.java b/src/edu/greenriver/sdev333/SequentialSearchST.java
index 1f79924..3d24db4 100644
--- a/src/edu/greenriver/sdev333/SequentialSearchST.java
+++ b/src/edu/greenriver/sdev333/SequentialSearchST.java
@@ -1,29 +1,80 @@
package edu.greenriver.sdev333;
+import javax.xml.crypto.dsig.keyinfo.KeyValue;
+
/**
* Sequential search (unordered linked list implementation) of Symbol Table
* Refer to p. 374-377 in Sedgewick and Wayne, Algorithms, 4th edition
* @param
* @param
*/
+
+//The class SequentialSearchST is defined with two generic type parameters, KeyType and ValueType,
+// which represent the types of keys and values that can be stored in the symbol table.
public class SequentialSearchST implements SymbolTable {
+ private Node first;
+ //The Node class is a private nested class that represents each element of the linked list.
+ // Each Node object contains a key-value pair and a reference to the next node in the list.
+ private class Node{
+ KeyType key;
+ ValueType value;
+ Node next;
+
+ public Node(KeyType key, ValueType value, Node next)
+ {
+ this.key = key;
+ this.value = value;
+ this.next = next;
+ }
+ }
+ //The put method takes a key-value pair and inserts it into the linked list.
+ // It does this by iterating through the list, starting at the first node, and comparing each node's key to the key provided as an argument.
+ // If the keys match, the method updates the node's value and returns. Otherwise,
+ // the method inserts a new node containing the key-value pair at the beginning of the list.
@Override
public void put(KeyType key, ValueType value) {
-
+ for (Node x = first; x != null; x = x.next)
+ if (key.equals(x.key))
+ {
+ x.value = value;
+ return;
+ }
+ first = new Node(key, value, first);
}
+ //The get method takes a key and searches for the corresponding value in the linked list.
+ // It does this by iterating through the list, starting at the first node, and comparing each node's key to the key provided as an argument.
+ // If the keys match, the method returns the corresponding value. If no node with a matching key is found, the method returns null.
@Override
public ValueType get(KeyType key) {
+ for (Node x = first; x != null; x = x.next)
+ if( key.equals(x.key))
+ return x.value;
return null;
}
+ //The size method returns the number of nodes in the linked list.
+ // Since the implementation uses an unordered linked list, there is no efficient way
+ // to count the number of elements without iterating through the entire list, so this method always returns 0.
@Override
public int size() {
return 0;
}
+ //The keys method returns an iterable object containing all the keys in the symbol table.
+ // Since the implementation uses an unordered linked list, there is no efficient way to iterate through the
+ // keys without iterating through the entire list, so this method returns null.
@Override
public Iterable keys() {
- return null;
+ // Create an empty queue
+ Queue queue = new Queue<>();
+ //create a current and start it at front
+ Node current = first;
+ //walk current to the back of the list
+ while (current != null) {
+ queue.enqueue(current.key);
+ current = current.next;
+ }
+ return queue;
}
}
diff --git a/src/edu/greenriver/sdev333/SymbolTable.java b/src/edu/greenriver/sdev333/SymbolTable.java
index 1b5a8f5..97a88b6 100644
--- a/src/edu/greenriver/sdev333/SymbolTable.java
+++ b/src/edu/greenriver/sdev333/SymbolTable.java
@@ -14,7 +14,7 @@ default void delete(KeyType key) {
put(key, null);
}
default boolean contains(KeyType key) {
- return get(key) == null;
+ return get(key) != null;
}
default boolean isEmpty() {
return size() == 0;