183 lines
5.6 KiB
Java
183 lines
5.6 KiB
Java
|
|
||
|
|
||
|
import edu.princeton.cs.introcs.StdIn;
|
||
|
import edu.princeton.cs.introcs.StdOut;
|
||
|
|
||
|
/*************************************************************************
|
||
|
* Compilation: javac SequentialSearchST.java
|
||
|
* Execution: java SequentialSearchST
|
||
|
* Dependencies: StdIn.java StdOut.java
|
||
|
* Data files: http://algs4.cs.princeton.edu/31elementary/tinyST.txt
|
||
|
*
|
||
|
* Symbol table implementation with sequential search in an
|
||
|
* unordered linked list of key-value pairs.
|
||
|
*
|
||
|
* % more tinyST.txt
|
||
|
* S E A R C H E X A M P L E
|
||
|
*
|
||
|
* % java SequentialSearchST < tiny.txt
|
||
|
* L 11
|
||
|
* P 10
|
||
|
* M 9
|
||
|
* X 7
|
||
|
* H 5
|
||
|
* C 4
|
||
|
* R 3
|
||
|
* A 8
|
||
|
* E 12
|
||
|
* S 0
|
||
|
*
|
||
|
*************************************************************************/
|
||
|
|
||
|
/**
|
||
|
* The SequentialSearchST class represents an (unordered)
|
||
|
* symbol table of generic key-value pairs.
|
||
|
* It supports the usual put , get , contains ,
|
||
|
* delete , size , and is-empty methods.
|
||
|
* It also provides a keys method for iterating over all of the keys.
|
||
|
* A symbol table implements the associative array abstraction:
|
||
|
* when associating a value with a key that is already in the symbol table,
|
||
|
* the convention is to replace the old value with the new value.
|
||
|
* The class also uses the convention that values cannot be null . Setting the
|
||
|
* value associated with a key to null is equivalent to deleting the key
|
||
|
* from the symbol table.
|
||
|
*
|
||
|
* This implementation uses a singly-linked list and sequential search.
|
||
|
* It relies on the equals() method to test whether two keys
|
||
|
* are equal. It does not call either the compareTo() or
|
||
|
* hashCode() method.
|
||
|
* The put and delete operations take linear time; the
|
||
|
* get and contains operations takes linear time in the worst case.
|
||
|
* The size , and is-empty operations take constant time.
|
||
|
* Construction takes constant time.
|
||
|
*
|
||
|
* For additional documentation, see <a href="http://algs4.cs.princeton.edu/31elementary">Section 3.1</a> of
|
||
|
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
|
||
|
*
|
||
|
* @author Robert Sedgewick
|
||
|
* @author Kevin Wayne
|
||
|
*/
|
||
|
public class SequentialSearchST<Key, Value> {
|
||
|
private int N; // number of key-value pairs
|
||
|
private Node first; // the linked list of key-value pairs
|
||
|
|
||
|
// a helper linked list data type
|
||
|
private class Node {
|
||
|
private Key key;
|
||
|
private Value val;
|
||
|
private Node next;
|
||
|
|
||
|
public Node(Key key, Value val, Node next) {
|
||
|
this.key = key;
|
||
|
this.val = val;
|
||
|
this.next = next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Initializes an empty symbol table.
|
||
|
*/
|
||
|
public SequentialSearchST() {
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the number of key-value pairs in this symbol table.
|
||
|
* @return the number of key-value pairs in this symbol table
|
||
|
*/
|
||
|
public int size() {
|
||
|
return N;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Is this symbol table empty?
|
||
|
* @return true if this symbol table is empty and false otherwise
|
||
|
*/
|
||
|
public boolean isEmpty() {
|
||
|
return size() == 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Does this symbol table contain the given key?
|
||
|
* @param key the key
|
||
|
* @return true if this symbol table contains key and
|
||
|
* false otherwise
|
||
|
*/
|
||
|
public boolean contains(Key key) {
|
||
|
return get(key) != null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the value associated with the given key.
|
||
|
* @param key the key
|
||
|
* @return the value associated with the given key if the key is in the symbol table
|
||
|
* and null if the key is not in the symbol table
|
||
|
*/
|
||
|
public Value get(Key key) {
|
||
|
for (Node x = first; x != null; x = x.next) {
|
||
|
if (key.equals(x.key)) return x.val;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Inserts the key-value pair into the symbol table, overwriting the old value
|
||
|
* with the new value if the key is already in the symbol table.
|
||
|
* If the value is null , this effectively deletes the key from the symbol table.
|
||
|
* @param key the key
|
||
|
* @param val the value
|
||
|
*/
|
||
|
public void put(Key key, Value val) {
|
||
|
if (val == null) { delete(key); return; }
|
||
|
for (Node x = first; x != null; x = x.next)
|
||
|
if (key.equals(x.key)) { x.val = val; return; }
|
||
|
first = new Node(key, val, first);
|
||
|
N++;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes the key and associated value from the symbol table
|
||
|
* (if the key is in the symbol table).
|
||
|
* @param key the key
|
||
|
*/
|
||
|
public void delete(Key key) {
|
||
|
first = delete(first, key);
|
||
|
}
|
||
|
|
||
|
// delete key in linked list beginning at Node x
|
||
|
// warning: function call stack too large if table is large
|
||
|
private Node delete(Node x, Key key) {
|
||
|
if (x == null) return null;
|
||
|
if (key.equals(x.key)) { N--; return x.next; }
|
||
|
x.next = delete(x.next, key);
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Returns all keys in the symbol table as an Iterable .
|
||
|
* To iterate over all of the keys in the symbol table named st ,
|
||
|
* use the foreach notation: for (Key key : st.keys()) .
|
||
|
* @return all keys in the sybol table as an Iterable
|
||
|
*/
|
||
|
public Iterable<Key> keys() {
|
||
|
Queue<Key> queue = new Queue<Key>();
|
||
|
for (Node x = first; x != null; x = x.next)
|
||
|
queue.enqueue(x.key);
|
||
|
return queue;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Unit tests the SequentialSearchST data type.
|
||
|
*/
|
||
|
public static void main(String[] args) {
|
||
|
SequentialSearchST<String, Integer> st = new SequentialSearchST<String, Integer>();
|
||
|
for (int i = 0; !StdIn.isEmpty(); i++) {
|
||
|
String key = StdIn.readString();
|
||
|
st.put(key, i);
|
||
|
}
|
||
|
for (String s : st.keys())
|
||
|
StdOut.println(s + " " + st.get(s));
|
||
|
}
|
||
|
}
|